From bf82e9cfa8fc2b627af6e2fcfcbc1bbfc61e63d9 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 23 Mar 2023 07:37:57 -0700 Subject: match: support @nil in predicates. For instance @(<= 10 @nil 20) is a pattern which matches a number between 10 and 20, without binding a variable. * stdlib/match.tl (compile-predicate-match): Looks like this code was already halfway expressing the intent that the avar could be nil, because arg-var takes the value of avar if that is non-nil, otherwise a gensym is substituted. What was missing was that the gensym that replaces nil must also be substituted into the predicate. * tests/011/patmatch.tl: New tests. * txr.1: Document that the variable embedded in a predicate may be null. --- stdlib/match.tl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'stdlib') diff --git a/stdlib/match.tl b/stdlib/match.tl index 3adbba27..c59179f3 100644 --- a/stdlib/match.tl +++ b/stdlib/match.tl @@ -275,21 +275,27 @@ (if (and (consp head) (eq (car head) 'sys:var)) (tree-case exp (((t rvar) (op . args)) - (let* ((avar + (let* ((arg-var (gensym "obj-")) + (avar (condlet (((vm (member-if [andf consp (op eq (car @1) 'sys:var)] args))) (let ((sym (cadar vm))) + (if (null sym) + (set sym arg-var) + (set arg-var sym)) (set args (append (ldiff args vm) (list sym) (cdr vm))) sym)) (((vm (memq 'sys:var args))) (let ((sym (cadr vm))) + (if (null sym) + (set sym arg-var) + (set arg-var sym)) (set args (append (ldiff args vm) sym)) sym)))) - (res-var (gensym "res-")) - (arg-var (if avar avar (gensym "obj-")))) + (res-var (gensym "res-"))) (unless avar (set args (append args (list arg-var)))) (let* ((guard (new match-guard -- cgit v1.2.3