diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-10-13 07:21:53 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-10-13 07:21:53 -0700 |
commit | 8629f3e1eb6860d72861800ed5004cf0ae5dd2b3 (patch) | |
tree | 6759fa8e04ff5514aaaefb1020b99de2d2e01041 | |
parent | ae644e2046349d2fdb83da88a33bedb565b99dce (diff) | |
download | txr-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.c | 1 | ||||
-rw-r--r-- | stdlib/doc-syms.tl | 2 | ||||
-rw-r--r-- | stdlib/place.tl | 19 | ||||
-rw-r--r-- | txr.1 | 73 |
4 files changed, 87 insertions, 8 deletions
@@ -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) @@ -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 *) |