[parenscript-devel] Patch: destructuring-bind now supports dotted lists and nested lists

Daniel Gackle danielgackle at gmail.com
Sat Jul 11 02:26:08 UTC 2009


A couple of examples, followed by patch:

(ps (destructuring-bind (a . rest) list
          (blah a rest)))
=>
"var a = list[0];
var rest = list.length > 1 ? list.slice(1) : null;
blah(a, rest);"

(ps (destructuring-bind ((a (b c)) (d e)) list))
=>
"var _js42 = list[0];
var a = _js42[0];
var _js43 = _js42[1];
var b = _js43[0];
var c = _js43[1];
var _js44 = list[1];
var d = _js44[0];
var e = _js44[1];"


>From 74d29fe528d40795071e61df4fb1e4b56b28f049 Mon Sep 17 00:00:00 2001
From: Daniel Gackle <danielgackle at gmail.com>
Date: Fri, 10 Jul 2009 16:31:55 -0600
Subject: [PATCH 1/2] DESTRUCTURING-BIND can now handle dotted and nested
binding lists.

---
 src/lib/ps-macro-lib.lisp |   31 +++++++++++++++++++++----------
 1 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/lib/ps-macro-lib.lisp b/src/lib/ps-macro-lib.lisp
index 1013939..d70561c 100644
--- a/src/lib/ps-macro-lib.lisp
+++ b/src/lib/ps-macro-lib.lisp
@@ -144,14 +144,25 @@
                      (first args))))
     `((@ ,fn :apply) this ,arglist)))

-(defpsmacro destructuring-bind (vars expr &body body)
-  ;; a simple implementation that for now only supports flat lists,
-  ;; but does allow NIL bindings to indicate ignore (a la LOOP)
+(defun destructuring-wrap (arr n bindings body)
+  (cond ((null bindings)
+         body)
+        ((atom bindings)
+         ;; dotted destructuring list
+         `(let ((,bindings (when (> (length ,arr) ,n)
+                             ((@ ,arr :slice) ,n))))
+            ,body))
+        (t (let ((var (car bindings))
+                 (inner-body (destructuring-wrap arr (1+ n) (cdr bindings)
body)))
+             (cond ((null var) inner-body)
+                   ((atom var) `(let ((,var (aref ,arr ,n)))
+                                  ,inner-body))
+                   (t `(destructuring-bind ,var (aref ,arr ,n)
+                         ,inner-body)))))))
+
+(defpsmacro destructuring-bind (bindings expr &body body)
   (let* ((arr (if (complex-js-expr? expr) (ps-gensym) expr))
-         (n -1)
-         (bindings
-          (append (unless (equal arr expr) `((,arr ,expr)))
-                  (mapcan (lambda (var)
-                            (incf n)
-                            (when var `((,var (aref ,arr ,n))))) vars))))
-    `(let* ,bindings , at body)))
+         (bound (destructuring-wrap arr 0 bindings (cons 'progn body))))
+    (if (eq arr expr)
+        bound
+        `(let ((,arr ,expr)) ,bound))))
-- 
1.6.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/parenscript-devel/attachments/20090710/1a9c642a/attachment.html>


More information about the parenscript-devel mailing list