summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-10-13 20:23:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-10-13 20:23:35 -0700
commit378546295be6b3a72ee3792d9175501bc77c016d (patch)
treebafa7f54ab53ae1edb96cdce20165f4bdf18d88b
parent8b00ff477f752ea4e11290be398b5a3cf98cf7ab (diff)
downloadtxr-378546295be6b3a72ee3792d9175501bc77c016d.tar.gz
txr-378546295be6b3a72ee3792d9175501bc77c016d.tar.bz2
txr-378546295be6b3a72ee3792d9175501bc77c016d.zip
New function: macroexpand-struct-clause.
* stdlib/struct.tl (macroexpand-struct-clause): New function. * autoload.c (struct_set_entries): Autoload struct module on macroexpand-struct-clause. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
-rw-r--r--autoload.c2
-rw-r--r--stdlib/doc-syms.tl1
-rw-r--r--stdlib/struct.tl5
-rw-r--r--txr.150
4 files changed, 57 insertions, 1 deletions
diff --git a/autoload.c b/autoload.c
index e266ed43..7a6cd79d 100644
--- a/autoload.c
+++ b/autoload.c
@@ -220,7 +220,7 @@ static val struct_set_entries(val fun)
lit("defstruct"), lit("qref"), lit("uref"), lit("new"), lit("lnew"),
lit("new*"), lit("lnew*"),
lit("meth"), lit("umeth"), lit("usl"), lit("defmeth"), lit("rslot"),
- lit("define-struct-clause"), nil
+ lit("define-struct-clause"), lit("macroexpand-struct-clause"), nil
};
val vname[] = {
lit("*struct-clause-expander*"), nil
diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl
index 2b0edcaf..08dcc8e2 100644
--- a/stdlib/doc-syms.tl
+++ b/stdlib/doc-syms.tl
@@ -1190,6 +1190,7 @@
("macroexpand-match" "N-02CCCB67")
("macroexpand-params" "N-037EB49A")
("macroexpand-place" "N-00684FF9")
+ ("macroexpand-struct-clause" "N-01046265")
("macrolet" "N-00AC12C0")
("madv-dontneed" "N-027D1E84")
("madv-normal" "N-027D1E84")
diff --git a/stdlib/struct.tl b/stdlib/struct.tl
index 10b07710..855ac6e1 100644
--- a/stdlib/struct.tl
+++ b/stdlib/struct.tl
@@ -415,6 +415,11 @@
(mac-param-bind ,form ,params (cdr ,slot) ,*body)))
,keyword)))
+(defun macroexpand-struct-clause (clause : form)
+ (iflet ((xfun (and (consp clause) [*struct-clause-expander* (car clause)])))
+ [xfun clause form]
+ (cons clause nil)))
+
(compile-only
(load-for (struct sys:param-parser-base "param")))
diff --git a/txr.1 b/txr.1
index 4c2ee369..cfd70018 100644
--- a/txr.1
+++ b/txr.1
@@ -32313,6 +32313,56 @@ or a subtype thereof.
fa.(write 4) -> ;; error: fa has no such method
.brev
+.coNP Function @ macroexpand-struct-clause
+.synb
+.mets (macroexpand-struct-clause < clause <> [ form ])
+.syne
+.desc
+If
+.code clause
+is a compound expression whose operator symbol was defined by
+.code define-struct-clause
+then
+.code macroexpand-struct-clause
+expands the clause and returns the expansion, which is
+a list of zero or more clauses.
+Otherwise, the function returns a one-element list containing the
+.meta clause
+argument, as if by the
+.mono
+.meti (list << clause )
+.onom
+expression.
+
+The
+.meta form
+parameter, if present, is used for reporting errors.
+Note: clauses are usually expanded during the processing of a
+.code defstruct
+macro; in that situation, the entire unexpanded
+.code defstruct
+form serves the role,
+
+.TP* Examples:
+
+.verb
+ ;; try to expand :delegate, using incorrect syntax.
+ (macroexpand-struct-clause '(:delegate x (a b)))
+ --> error "** source location n/a: nil: too few elements ..."
+
+ ;; same, but with error reporting form.
+ (macroexpand-struct-clause '(:delegate x (a b)) '(abc xyz))
+ --> error: "** expr-1:1: abc: too few elements ..."
+
+ ;; correct :delegate syntax
+ (macroexpand-struct-clause '(:delegate x (a b) a.foo))
+ --> ((:method x (a b) (qref a.foo (x b))))
+
+ ;; not a defstruct macro clause
+ (macroexpand-struct-clause '(1 2 3))
+ -> ((1 2 3))
+.brev
+
.coNP Special variable @ *struct-clause-expander*
.desc
The