summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-10-13 07:21:53 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-10-13 07:21:53 -0700
commit8629f3e1eb6860d72861800ed5004cf0ae5dd2b3 (patch)
tree6759fa8e04ff5514aaaefb1020b99de2d2e01041
parentae644e2046349d2fdb83da88a33bedb565b99dce (diff)
downloadtxr-8629f3e1eb6860d72861800ed5004cf0ae5dd2b3.tar.gz
txr-8629f3e1eb6860d72861800ed5004cf0ae5dd2b3.tar.bz2
txr-8629f3e1eb6860d72861800ed5004cf0ae5dd2b3.zip
New function: macroexpand-place.
* stdlib/place.tl (sys:pl-expand): Function renamed to macroexpand-place; env parameter becomes optional. (macroexpand-1-place): New function. (place-form-p, call-update-expander, call-clobber-expander, call-delete-expander): Follow rename. * autoload.c (place_set_entries): Register symbols macroexpand-place and macroexpand-1-place for autoload. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
-rw-r--r--autoload.c1
-rw-r--r--stdlib/doc-syms.tl2
-rw-r--r--stdlib/place.tl19
-rw-r--r--txr.173
4 files changed, 87 insertions, 8 deletions
diff --git a/autoload.c b/autoload.c
index a3430a63..336c2518 100644
--- a/autoload.c
+++ b/autoload.c
@@ -109,6 +109,7 @@ static val place_set_entries(val fun)
lit("defplace"), lit("define-place-macro"), lit("define-modify-macro"),
lit("placelet"), lit("placelet*"), lit("read-once"),
lit("define-accessor"), lit("with-slots"),
+ lit("macroexpand-place"), lit("macroexpand-1-place"),
nil
};
diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl
index d6c001c1..e75ad2c7 100644
--- a/stdlib/doc-syms.tl
+++ b/stdlib/doc-syms.tl
@@ -1185,8 +1185,10 @@
("macroexpand" "N-02ED5471")
("macroexpand-1" "N-02ED5471")
("macroexpand-1-lisp1" "N-01E62179")
+ ("macroexpand-1-place" "N-00684FF9")
("macroexpand-lisp1" "N-01E62179")
("macroexpand-params" "N-037EB49A")
+ ("macroexpand-place" "N-00684FF9")
("macrolet" "N-00AC12C0")
("madv-dontneed" "N-027D1E84")
("madv-normal" "N-027D1E84")
diff --git a/stdlib/place.tl b/stdlib/place.tl
index 07ee7be4..fcc86735 100644
--- a/stdlib/place.tl
+++ b/stdlib/place.tl
@@ -63,7 +63,7 @@
(or [*place-macro* sym]
(progn (sys:autoload-try-fun sym) [*place-macro* sym])))
-(defun sys:pl-expand (unex-place env)
+(defun macroexpand-place (unex-place : env)
(while t
(let ((place unex-place)
pm-expander)
@@ -76,11 +76,18 @@
(when (or (eq place unex-place)
(null place)
(and (atom place) (not (symbolp place))))
- (return-from sys:pl-expand place))
+ (return-from macroexpand-place place))
(sys:setq unex-place place))))
+(defun macroexpand-1-place (unex-place : env-unused)
+ (let ((pm-expander (if (consp unex-place)
+ (sys:get-place-macro (car unex-place)))))
+ (if pm-expander
+ [pm-expander unex-place]
+ unex-place)))
+
(defun place-form-p (unex-place env)
- (let ((place (sys:pl-expand unex-place env)))
+ (let ((place (macroexpand-place unex-place env)))
(or (bindable place)
(and (consp place) [*place-update-expander* (car place)] t))))
@@ -147,7 +154,7 @@
(defun call-update-expander (getter setter unex-place env body)
(sys:propagate-ancestor body unex-place getter setter)
- (let* ((place (sys:pl-expand unex-place env))
+ (let* ((place (macroexpand-place unex-place env))
(expander (get-update-expander place))
(sys:*pl-env* env)
(sys:*pl-form* unex-place)
@@ -157,7 +164,7 @@
(defun call-clobber-expander (ssetter unex-place env body)
(sys:propagate-ancestor body unex-place ssetter)
- (let* ((place (sys:pl-expand unex-place env))
+ (let* ((place (macroexpand-place unex-place env))
(expander (get-clobber-expander place))
(sys:*pl-env* env)
(sys:*pl-form* unex-place)
@@ -167,7 +174,7 @@
(defun call-delete-expander (deleter unex-place env body)
(sys:propagate-ancestor body unex-place deleter)
- (let* ((place (sys:pl-expand unex-place env))
+ (let* ((place (macroexpand-place unex-place env))
(expander (get-delete-expander place))
(sys:*pl-env* env)
(sys:*pl-form* unex-place)
diff --git a/txr.1 b/txr.1
index 5d2f076f..9a3578b3 100644
--- a/txr.1
+++ b/txr.1
@@ -41713,12 +41713,12 @@ contains no parameter macro invocations, then it is returned.
The optional
.meta env
-parmeter specifies the macro environment which is passed to the
+parameter specifies the macro environment which is passed to the
parameter macro expanders, which they can receive via the
.code :env
parameter. The default value
.code nil
-sepcifies the top-level environment.
+specifies the top-level environment.
.TP* Examples:
@@ -43865,6 +43865,75 @@ in terms of
^(car ,obj))
.brev
+.coNP Functions @ macroexpand-place and @ macroexpand-1-place
+.synb
+.mets (macroexpand-1-place < form <> [ env ])
+.mets (macroexpand-place < form <> [ env ])
+.syne
+.desc
+If
+.meta form
+is a place macro form (a form whose operator symbol has been defined
+as a place macro using
+.codn define-place-macro )
+these functions expand the place macro form and return the expanded form.
+Otherwise, they return
+.metn form .
+
+.code macroexpand-place-1
+performs a single expansion, expanding only the place the macro
+that is referenced by the symbol in the first position of
+.metn form ,
+and returns the expansion. Note that if
+.meta form
+is an ordinary macro form, this function will not expand it,
+even if such an expansion would reveal a place macro form.
+
+.code macroexpand-place
+performs a full place expansion of
+.meta form
+by the following process.
+If
+.meta form
+is a place macro call, it is expanded, and the result is
+checked again to see whether it is a place macro, and
+expanded. This is repeated as many times as necessary
+until the result is no longer a place macro call.
+Then, if the resulting form is an ordinary macro invocation,
+it is expanded once as if by
+.codn macroexpand-1 .
+This process is iterated until a fixed point is reached.
+
+The optional
+.meta env
+parameter is a macro environment. Note: the
+.code macroexpand-place-1
+function ignores the
+.meta env
+parameter, which could change in the future.
+
+.TP* Examples
+
+Given this ordinary macro definition
+
+.verb
+ (defmacro leftmost (x) ^(first ,x))
+.brev
+
+the following results are obtained:
+
+.verb
+ ;; ordinary macro leftmost expands to first,
+ ;; then first place macro expands to car:
+ (macroexpand-place '(leftmost x)) -> (car x)
+
+ ;; macroexpand-1-place won't expand ordinary macro:
+ (macroexpand-1-place '(leftmost x)) -> (leftmost x)
+
+ ;; macroexpand-1-place expands place macro
+ (macroexpand-1-place '(first x)) -> (car x)
+.brev
+
.coNP Macro @ rlet
.synb
.mets (rlet >> ({( sym << init-form )}*) << body-form *)