diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-07-11 07:28:47 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-07-11 07:28:47 -0700 |
commit | f888430a6012947a9aea3624592dff1fc1f18726 (patch) | |
tree | 3b7af565caea3cd82de0d516c2a8e3b626841b9d | |
parent | 4ccc4bff6556940a1268d96ec60bb2f599f0fe6d (diff) | |
download | txr-f888430a6012947a9aea3624592dff1fc1f18726.tar.gz txr-f888430a6012947a9aea3624592dff1fc1f18726.tar.bz2 txr-f888430a6012947a9aea3624592dff1fc1f18726.zip |
Let's have placelet and placelet*.
* share/txr/stdlib/place.tl (placelet*): New macro.
* lisplib.c (place_set_entries): Add placelet* to list of names.
* txr.1: Updated to document placelet* and fix mistakes.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | lisplib.c | 2 | ||||
-rw-r--r-- | share/txr/stdlib/place.tl | 19 | ||||
-rw-r--r-- | txr.1 | 23 |
4 files changed, 46 insertions, 8 deletions
@@ -1,5 +1,15 @@ 2015-07-11 Kaz Kylheku <kaz@kylheku.com> + Let's have placelet and placelet*. + + * share/txr/stdlib/place.tl (placelet*): New macro. + + * lisplib.c (place_set_entries): Add placelet* to list of names. + + * txr.1: Updated to document placelet* and fix mistakes. + +2015-07-11 Kaz Kylheku <kaz@kylheku.com> + * share/txr/stdlib/place.tl (defplace dwim): Eliminate ogetter-sym variable for caching the sequence; use the getter for the sequence place to access it. Again, this is for placelet, @@ -68,7 +68,7 @@ static val place_set_entries(val dlt, val fun) lit("push"), lit("pop"), lit("swap"), lit("shift"), lit("rotate"), lit("pushnew"), lit("del"), lit("defplace"), lit("define-modify-macro"), - lit("placelet"), + lit("placelet"), lit("placelet*"), nil }; diff --git a/share/txr/stdlib/place.tl b/share/txr/stdlib/place.tl index 9cae3974..7bb059a8 100644 --- a/share/txr/stdlib/place.tl +++ b/share/txr/stdlib/place.tl @@ -570,14 +570,25 @@ (call-update-expander pl-getter pl-setter place env ^(macrolet ((,tmp-place () ^(,',pl-getter))) ,(sys:expand - ^(symacrolet ((,sym (,tmp-place))) ,*body) + ^(symacrolet ((,sym (,tmp-place))) + ,*body) env)))) (remhash *place-update-expander* tmp-place)))) -(defmacro placelet (sym-place-pairs . body) +(defmacro placelet* (sym-place-pairs . body) (tree-case sym-place-pairs (() ^(progn ,*body)) (((sym place)) ^(sys:placelet-1 ((,sym ,place)) ,*body)) (((sym place) . rest-pairs) ^(sys:placelet-1 ((,sym ,place)) - (placelet (,*rest-pairs) ,*body))) - (obj (throwf 'eval-error "placelet: bad syntax: ~s" obj)))) + (placelet* (,*rest-pairs) ,*body))) + (obj (throwf 'eval-error "placelet*: bad syntax: ~s" obj)))) + +(defmacro placelet (sym-place-pairs . body) + (unless (all sym-place-pairs + [andf consp (opip length (= 2)) (oand first bindable)]) + (throwf 'eval-error "placelet: bad syntax: ~s" sym-place-pairs)) + (tree-bind (: syms places) (transpose sym-place-pairs) + (let ((temps (mapcar (ret (gensym)) syms))) + ^(placelet* (,*(zip temps places)) + (symacrolet (,*(zip syms temps)) + ,*body))))) @@ -28679,9 +28679,10 @@ applies inside a form. Of course, lexical operator macros do not shadow symbol macros under any circumstances. -.coNP Operator @ placelet +.coNP Macros @ placelet and @ placelet* .synb .mets (placelet >> ({( sym << place )}*) << body-form *) +.mets (placelet* >> ({( sym << place )}*) << body-form *) .syne .desc The @@ -28710,10 +28711,26 @@ scope of the This means that whenever .meta sym is evaluated, it stands for the value of the storage -location, and whenever a value is apprently stored into +location, and whenever a value is apparently stored into .metn sym , it is actually the storage location which receives it. +The +.code placelet* +variant implements an alternative scoping rule, which allows a later +.meta place +form to refer to a +.meta sym +bound to an earlier +.meta place +form. In other words, a given +.meta sym +binding is visible not only to the +.metn body-form -s +but also to +.meta place +forms which occur later. + Note: certain kinds of places, notably .cblk .meti (force << promise ) @@ -28735,7 +28752,7 @@ performs the syntactic substitution of symbol .code x by form .codn y , -whereever +wherever .code x appears inside .code z |