summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-01-17 00:29:26 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-01-17 00:29:26 -0800
commit3332d4a1e9f03caa748395ee200b1efcb05d535f (patch)
tree2759b09f3f343320b3a94066928cb593f87400d8 /txr.1
parentaf7dde6d9ebe2b6d232179be7920e8b9aaffd197 (diff)
downloadtxr-3332d4a1e9f03caa748395ee200b1efcb05d535f.tar.gz
txr-3332d4a1e9f03caa748395ee200b1efcb05d535f.tar.bz2
txr-3332d4a1e9f03caa748395ee200b1efcb05d535f.zip
matcher: support loose mode for structures.
* share/txr/stdlib/match.tl (compile-struct-match): Allow a pattern instead of a struct type name, in which case the object can be of any struct type which has the slots required by the pattern. * txr.1: Documented.
Diffstat (limited to 'txr.1')
-rw-r--r--txr.171
1 files changed, 65 insertions, 6 deletions
diff --git a/txr.1 b/txr.1
index 8578ec3c..91f8af9d 100644
--- a/txr.1
+++ b/txr.1
@@ -39782,16 +39782,28 @@ against the corresponding vector element.
.NP* Structure match
.synb
.mets @(structure << name >> { slot-name << pattern }*)
+.mets @(structure << pattern >> { slot-name << pattern }*)
.syne
.desc
-The structure pattern operator matches a structure object.
-The first argument of the pattern operator is a symbol which gives the name of
-the structure type. The corresponding object being matched must be a structure
-instance, and must be of this type, otherwise there is no match
+The structure pattern operator matches a structure object. The operator
+supports two modes of matching, the choice of which depends on whether the
+first argument is a
+.meta name
+or a
+.metn pattern .
+
+The first argument is considered a
+.meta name
+if it is a bindable symbol according to the
+.code bindable
+function. In this situation, the operator operates in
+strict mode. Otherwise, the operator is in loose mode.
The
.meta name
-is followed by zero or more
+or
+.meta pattern
+argument is followed by zero or more
.meta "slot-name pattern"
pairs, which are not enclosed in lists, similarly to the way
slots are presented in the
@@ -39800,11 +39812,39 @@ struct syntax and in the argument conventions of the
.code new
macro.
-Each
+In strict mode,
+.meta name
+is assumed to be the name of an existing struct type.
+The object being matched is tested whether it is a subtype of this type, as
+if using the
+.code subtypep
+function. If it isn't, the match fails.
+
+In loose mode, the object being matched is tested whether it is a structure
+object of any structure type. If it isn't, the match fails.
+
+In strict mode, each
.meta "slot-name pattern"
pair requires that the object's slot of that name contain
a value which matches
.metn pattern .
+The operator assumes that all the
+.metn slot-name -s
+are slots of the struct type indicated by
+.metn name .
+
+In loose mode, no assumption is made that the object actually has the
+slots specified by the
+.meta slot-name
+arguments. The object's structure type is inquired to
+determine whether it has each of those slots. If it doesn't, the match fails.
+If the object has the required slots, then the values of those slots are
+matched against the patterns.
+
+In loose mode, the
+.meta pattern
+given in the first argument position of the syntax is matched against the
+object's structure type: the type itself, rather than its symbolic name.
.TP* Examples:
@@ -39815,6 +39855,25 @@ a value which matches
(when-match @(struct time year 2021 month @m)
#S(time year 2021 month 1)
m) -> 1
+
+ ;; match any structure with name and value slots,
+ ;; whose name is foo, and extract the value.
+
+ (defstruct widget ()
+ name
+ value)
+
+ (defstruct grommet ()
+ name
+ value)
+
+ (append-each ((obj (list (new grommet name "foo" value :grom)
+ (new widget name "foo" value :widg))))
+ (when-match @(struct @type name "foo" value @v) obj
+ (list (list type v))))
+
+ --> ((#<struct-type grommet> :grom)
+ (#<struct-type widget> :widg))
.brev
.SS* Quasiquote Operator Syntax