summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisplib.c2
-rw-r--r--share/txr/stdlib/yield.tl28
-rw-r--r--txr.122
3 files changed, 51 insertions, 1 deletions
diff --git a/lisplib.c b/lisplib.c
index a486abe1..1008912f 100644
--- a/lisplib.c
+++ b/lisplib.c
@@ -299,7 +299,7 @@ static val yield_set_entries(val dlt, val fun)
val name[] = {
lit("obtain"), lit("obtain-block"), lit("yield-from"), lit("yield"),
lit("obtain*"), lit("obtain*-block"),
- lit("suspend"),
+ lit("suspend"), lit("hlet"), lit("hlet*"),
nil
};
set_dlt_entries(dlt, name, fun);
diff --git a/share/txr/stdlib/yield.tl b/share/txr/stdlib/yield.tl
index 3ab74745..f8b5783d 100644
--- a/share/txr/stdlib/yield.tl
+++ b/share/txr/stdlib/yield.tl
@@ -88,3 +88,31 @@
^(sys:capture-cont ',name (lambda (,sym)
(sys:abscond-from ,name (progn ,*body)))
',form))
+
+(defun hlet-expand (op raw-vis body)
+ (let* ((vis (mapcar [iffi atom list] raw-vis))
+ (nvars (len vis))
+ (syms [mapcar car vis])
+ (inits [mapcar cadr vis])
+ (letop (if (eq op 'hlet*) 'let* 'let))
+ (gens (mapcar (ret (gensym)) vis))
+ (vec (gensym))
+ (macs (mapcar (ret ^(,@1 (vecref ,vec ,@2)))
+ syms (range 0)))
+ (inits (mapcar (ret ^(set (vecref ,vec ,@1) ,@2))
+ (range 0) inits)))
+ (if (eq op 'hlet*)
+ ^(let* ((,vec (vector ,nvars)))
+ (symacrolet ,macs
+ ,*inits
+ ,*body))
+ ^(let* ((,vec (vector ,nvars)))
+ ,*inits
+ (symacrolet ,macs
+ ,*body)))))
+
+(defmacro hlet (var-inits . body)
+ (hlet-expand 'hlet var-inits body))
+
+(defmacro hlet* (var-inits . body)
+ (hlet-expand 'hlet* var-inits body))
diff --git a/txr.1 b/txr.1
index fd1a6b76..bf05c548 100644
--- a/txr.1
+++ b/txr.1
@@ -38563,6 +38563,28 @@ non-deterministically:
-> (2 4)
.cble
+.coNP Macros @ hlet and @ hlet*
+.synb
+.mets (hlet >> ({ sym | >> ( sym << init-form )}*) << body-form *)
+.mets (hlet* >> ({ sym | >> ( sym << init-form )}*) << body-form *)
+.syne
+.desc
+The
+.code hlet
+and
+.code hlet*
+macros behave exactly like
+.code let
+and
+.codn let* ,
+respectively except that they guarantee that the variable bindings are
+allocated in storage which isn't captured by delimited continuations.
+
+The
+.code h
+in the names stands for "heap", serving as a mnemonic based on the
+implementation concept of these bindings being "heap allocated".
+
.SS* Regular Expression Library
\*(TX provides a "pure" regular expression implementation based on automata