aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2019-03-31 23:33:57 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2019-04-01 16:22:04 +0200
commitae4246e67cd06f25a3bbfd1b745546eed829deda (patch)
tree2bec4da0acfb5215aa4a791c026bf11f0222a65b
parentAdd test for properties from scheme. (diff)
downloadcalp-ae4246e67cd06f25a3bbfd1b745546eed829deda.tar.gz
calp-ae4246e67cd06f25a3bbfd1b745546eed829deda.tar.xz
Add support for improper-lists in let*.
-rw-r--r--module/util.scm28
1 files changed, 21 insertions, 7 deletions
diff --git a/module/util.scm b/module/util.scm
index 2302f671..6770460e 100644
--- a/module/util.scm
+++ b/module/util.scm
@@ -71,16 +71,15 @@
(append public-fields private-fields))
,@(map (lambda (field) `(export ,field))
public-fields))))
- ;; (define-quick-record-templated 'define-immutable-record-type name fields))
-;; (define-macro (define-quick-record! name . fields)
-;; (define-quick-record-templated 'define-record-type name fields))
+
;; Replace let* with a version that can bind from lists.
;; Also supports SRFI-71 (extended let-syntax for multiple values)
;; @lisp
;; (let* ([a b (values 1 2)] ; @r{SRFI-71}
;; [(c d) '(3 4)] ; @r{Let-list (mine)}
+;; [(a b . c) (cons* 1 2 3)] ; @r{Improper list matching (mine)}
;; [e 5]) ; @r{Regular}
;; (list e d c b a))
;; ;; => (5 4 3 2 1)
@@ -93,13 +92,23 @@
(begin body ...)]
;; (let (((a b) '(1 2))) (list b a)) => (2 1)
- [(_ (((k k* ...) list-value) rest ...)
+ [(_ (((k ... . (k*)) list-value) rest ...)
body ...)
- (apply (lambda (k k* ...)
+ (apply (lambda (k ... k*)
(let* (rest ...)
- body ...))
+ body ...))
list-value)]
+ ;; Improper list matching
+ ;; (let* (((a b . c) (cons* 1 2 3))) (list a c)) ; => (1 3)
+ [(_ (((k1 k ... . k*) imp-list) rest ...)
+ body ...)
+ (apply (lambda (k1 k ... k*)
+ (let* (rest ...)
+ body ...))
+ (improper->proper-list
+ imp-list (length (quote (k1 k ...)))))]
+
;; "Regular" case
[(_ ((k value) rest ...) body ...)
(let ((k value))
@@ -112,9 +121,14 @@
(lambda (k k* ...)
(let* (rest ...)
body ...)))]
-
))
+(define (improper->proper-list lst len)
+ (let* ((head tail (split-at lst len)))
+ (append head (list tail))))
+
+
+
;; Like set!, but applies a transformer on the already present value.
(define-syntax-rule (mod! field transform-proc)
(set! field (transform-proc field)))