infix: Replace multiple-value constructs with a single bind.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 13 May 2006 00:13:52 +0000 (01:13 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 13 May 2006 00:15:44 +0000 (01:15 +0100)
This lets you do several layers of binding in one swoop, which is quite
shiny, really.  This covers multiple-value-bind and let (both the
single and multiple variable cases, if you're willing to use `values')
and multiple-value-setq is unnecessary since values is setf-able.

infix.lisp

index 93ec028..5cdd0b9 100644 (file)
@@ -34,7 +34,8 @@
           #:++ #:--
           #:<< #:>>
           #:if #:then #:else
-          #:let #:let* #:in))
+          #:let #:let* #:in
+          #:bind))
 
 (defpackage #:infix
   (:use #:common-lisp #:infix-keywords)
   (get-token)
   (pushval `(loop ,@(strip-progn (parse-infix 0)))))
 
-(defopfunc multiple-value-bind operand
-  (get-token)
-  (pushval `(multiple-value-bind
-               ,(parse-ident-list)
-               ,(progn (delim '=) (parse-infix))
-             ,@(progn (delim 'in) (strip-progn (parse-infix 0))))))
-
-(defopfunc multiple-value-setq operand
-  (get-token)
-  (pushval `(multiple-value-setq
-               ,(parse-ident-list)
-               ,(progn (delim '=) (parse-infix 0)))))
+(defopfunc bind operand
+  (labels ((loop ()
+           (let ((ids (parse-ident-list))
+                 (valform (progn (delim '=) (parse-infix 0)))
+                 (body (if (delim '|,| nil)
+                           (loop)
+                           (progn
+                             (delim 'in)
+                             (strip-progn (parse-infix 0))))))
+             (list (if (and ids (null (cdr ids)))
+                       `(let ((,(car ids) ,valform)) ,@body)
+                       `(multiple-value-bind ,ids ,valform ,@body))))))
+    (get-token)
+    (pushval (car (loop)))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Parsing function bodies and lambda lists.
      (labels ((foo (x) (+ x 1)) (bar (x) (- x 1))) (foo (bar y))))
     ("defun foo (x) x - 6" .
      (defun foo (x) (- x 6)))
-    ("multiple-value-bind x, y, z = values(4, 6, 8) in x + y + z" .
-     (multiple-value-bind (x y z) (values 4 6 8) (+ x y z)))))
+    ("bind x = 3 in x - 2" . (let ((x 3)) (- x 2)))
+    ("bind x, y = values(1, 2),
+           z = 3,
+           docs, decls, body = parse-body(body) in complicated" .
+     (multiple-value-bind (x y) (values 1 2)
+       (let ((z 3))
+        (multiple-value-bind (docs decls body) (parse-body body)
+          complicated))))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Debugging guff.