diff options
-rw-r--r-- | share/txr/stdlib/match.tl | 17 | ||||
-rw-r--r-- | txr.1 | 43 |
2 files changed, 47 insertions, 13 deletions
diff --git a/share/txr/stdlib/match.tl b/share/txr/stdlib/match.tl index ab12ef7d..ea0134fc 100644 --- a/share/txr/stdlib/match.tl +++ b/share/txr/stdlib/match.tl @@ -205,6 +205,21 @@ guard-chain (list (new match-guard guard-expr ^(equal ,obj-var ,sym))))))) +(defun compile-new-var-match (sym obj-var var-list) + (cond + ((null sym) + (new compiled-match + obj-var obj-var)) + ((not (bindable sym)) + (compile-error *match-form* "~s is not a bindable symbol" sym)) + (t var-list.(record sym) + (new compiled-match + pattern sym + obj-var obj-var + guard-chain (if sym (list (new match-guard + vars (list sym) + var-exprs (list obj-var)))))))) + (defun compile-vec-match (vec-pat obj-var var-list) (let* ((elem-gensyms (mapcar (op gensym `elem-@1-`) (range* 0 (len vec-pat)))) (elem-exprs (mapcar (ret ^[,obj-var ,@1]) (range* 0 (len vec-pat)))) @@ -327,7 +342,7 @@ (defun compile-as-match (exp obj-var var-list) (mac-param-bind *match-form* (op sym pat) exp - (let ((var-match (compile-var-match sym obj-var var-list)) + (let ((var-match (compile-new-var-match sym obj-var var-list)) (pat-match (compile-match pat obj-var var-list))) (new compiled-match pattern exp @@ -40273,10 +40273,13 @@ operator matching against an association list. .desc The .code as -pattern operator allows the entire object matched by a -.meta pattern -to be bound to a the variable given by -.metn name . +pattern operator binds the corresponding object to a fresh variable given by +.metn name , +similarly to the Lisp +.code let +operator. If another variable called +.meta name +exists, it is shadowed; thus, no back-referencing is performed. The .meta name @@ -40290,17 +40293,29 @@ then no name is bound. Thus .mono .meti @(as nil << pattern ) .onom -is equivalent to just +is equivalent to .metn pattern . - -If +Otherwise, .meta pattern -matches, then +processed in a scope in which the new .meta name -is included among the variables, and receives the entire -object matched by +binding is already visible. + +The +.code as +operator succeeds if .meta pattern -as its value. +matches. + +Note: the +.code and +operator can be used to bind a variable to an object, with back-referencing, in +parallel with other patterns which also match the object. However, all of the +elements of +.code and +are in separate scopes; back-referencing among branches of an +.code and +isn't possible. .TP* Example: @@ -40308,7 +40323,11 @@ as its value. ;; w captures the entire (1 2 3) list: (when-match @(as w (@a @b @c)) '(1 2 3) (list w a b c)) - -> ((1 2 3) 1 2 3) + --> ((1 2 3) 1 2 3) + + ;; match a list which has itself as the third element + (when-match @(as a (1 2 @a 4)) '#1=(1 2 #1# 4) :yes) + --> :yes .brev .coNP Pattern operator @ with |