summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-10-13 07:58:47 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-10-13 07:58:47 -0700
commit8b00ff477f752ea4e11290be398b5a3cf98cf7ab (patch)
tree6ddae1f89b191e0eb6733cef0ba53ab53971faec
parent8629f3e1eb6860d72861800ed5004cf0ae5dd2b3 (diff)
downloadtxr-8b00ff477f752ea4e11290be398b5a3cf98cf7ab.tar.gz
txr-8b00ff477f752ea4e11290be398b5a3cf98cf7ab.tar.bz2
txr-8b00ff477f752ea4e11290be398b5a3cf98cf7ab.zip
New function: macroexpand-match.
* stdlib/match.tl (macroexpand-match): New function. * autoload.c (match_set_entries): Autoload match module on macroexpand-match. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
-rw-r--r--autoload.c1
-rw-r--r--stdlib/doc-syms.tl1
-rw-r--r--stdlib/match.tl5
-rw-r--r--txr.150
4 files changed, 57 insertions, 0 deletions
diff --git a/autoload.c b/autoload.c
index 336c2518..e266ed43 100644
--- a/autoload.c
+++ b/autoload.c
@@ -826,6 +826,7 @@ static val match_set_entries(val fun)
lit("match"), lit("match-ecase"),
lit("while-match"), lit("while-match-case"), lit("while-true-match-case"),
lit("lambda-match"), lit("defun-match"), lit("defmatch"),
+ lit("macroexpand-match"),
lit("each-match"), lit("append-matches"),
lit("keep-matches"), lit("each-match-product"),
lit("append-match-products"), lit("keep-match-products"),
diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl
index e75ad2c7..2b0edcaf 100644
--- a/stdlib/doc-syms.tl
+++ b/stdlib/doc-syms.tl
@@ -1187,6 +1187,7 @@
("macroexpand-1-lisp1" "N-01E62179")
("macroexpand-1-place" "N-00684FF9")
("macroexpand-lisp1" "N-01E62179")
+ ("macroexpand-match" "N-02CCCB67")
("macroexpand-params" "N-037EB49A")
("macroexpand-place" "N-00684FF9")
("macrolet" "N-00AC12C0")
diff --git a/stdlib/match.tl b/stdlib/match.tl
index 55d50417..ff3134fd 100644
--- a/stdlib/match.tl
+++ b/stdlib/match.tl
@@ -833,6 +833,11 @@
,args ,*body)))
',name)))
+(defun macroexpand-match (pattern : env)
+ (iflet ((xfun (and (consp pattern) [*match-macro* (car pattern)])))
+ [xfun pattern env]
+ pattern))
+
(defun check (f op pat)
(if (or (not (listp pat))
(meq (car pat) 'sys:expr 'sys:var 'sys:quasi))
diff --git a/txr.1 b/txr.1
index 9a3578b3..4c2ee369 100644
--- a/txr.1
+++ b/txr.1
@@ -46939,6 +46939,56 @@ environment.
-> nil
.brev
+.coNP Function @ macroexpand-match
+.synb
+.mets (macroexpand-match < pattern <> [ env ])
+.syne
+.desc
+If
+.code pattern
+is a compound form whose operator symbol has been defined as a macro
+pattern using
+.codn defmatch ,
+then
+.code macroexpand-match
+will expand that pattern and return the expansion. Otherwise it returns the
+.code pattern
+argument.
+
+In order to be recognized by
+.code macroexpand-match
+the
+.meta pattern
+argument must not include the
+.code @
+prefix that would normally be used to invoke it. The expansion, however, will
+include that syntax.
+
+The
+.code env
+parameter specifies the macro-time environment for the expander.
+Note: pattern expanders, like built-in patterns, may use the macro environment
+for deciding whether a variable is an existing lexical variable, or a free
+variable, based on which a pattern may be expanded differently.
+
+.TP* Example:
+
+Given:
+.verb
+ (defmatch point (x y)
+ ^@(struct point x @,x y @,y))
+.brev
+a result similar to the following may be obtained:
+.verb
+ (macroexpand-match '(point a b)) -> @(struct point x @a y @b)
+.brev
+Note that the pattern is specified plainly as
+.code "(point a b)"
+rather than
+.codn "@(point a b)" ,
+yet the expansion is
+.codn "@(struct ...)" .
+
.coNP Special variable @ *match-macro*
.desc
The