From 9b8fce5acc9f27866b29ececbece109bbdef01f0 Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Wed, 21 Apr 2021 06:54:50 -0700
Subject: matcher: defmatch: useful :env parameter.

* share/txr/stdlib/match.tl (compile-match): Pattern macro
expanders now have an environment parameter. We turn the list
of variables that have been bound so far into a fake
macro-time lexical environment, the parent of which is the
surrounding environment. The pattern macro can query this
using the lexical-var-p function to determine whether a given
variable already has a binding, either in the pattern, or
in the surrounding lexical environment.
(defmatch): Generate a two-argument lambda, and use the new
mac-env-param-bind to make the environment object available
to the user-defined expansion.

* tests/011/patmatch.tl: New test cases for this environment
mechanism, and also for defmatch itself.

* txr.1: Document role of :env under defmatch.
---
 tests/011/patmatch.tl | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

(limited to 'tests/011/patmatch.tl')

diff --git a/tests/011/patmatch.tl b/tests/011/patmatch.tl
index 346b21b6..87545c82 100644
--- a/tests/011/patmatch.tl
+++ b/tests/011/patmatch.tl
@@ -321,3 +321,18 @@
 
 (test (when-match @(as z @(end (2 @x) y)) '(1 2 3) (list x y z))
       (3 (2 3) (1 2 3)))
+
+(defmatch env (var :env e)
+  ^@(with ,var ',e))
+
+(test (when-match @(and @a @(env e) @b) 42
+        (list a (env-vbindings e) (lexical-var-p e 'a) (lexical-var-p e 'b) b))
+      (42 ((a . sys:special)) t nil 42))
+
+(defmatch var= (sym :env e)
+  (if (lexical-var-p e sym)
+    (with-gensyms (obj)
+      ^@(require (sys:var ,obj) (= ,sym ,obj)))
+    ^(sys:var ,sym)))
+
+(test (when-match (@(var= a) @(var= a)) '(1 1.0) a) 1)
-- 
cgit v1.2.3