summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-12-26 20:30:22 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-12-26 20:30:22 -0800
commit4500f9d53feea9205c4c30743bb99e3a5f15703d (patch)
treeba0e308452e3bb8f3375a93ab23957e17421487e /match.c
parentd1caae1ac6f393d0bc8cbcf62804dbac0033d133 (diff)
downloadtxr-4500f9d53feea9205c4c30743bb99e3a5f15703d.tar.gz
txr-4500f9d53feea9205c4c30743bb99e3a5f15703d.tar.bz2
txr-4500f9d53feea9205c4c30743bb99e3a5f15703d.zip
txr: allow variable to span vertical function.
* match.c (v_var_compat, v_var): New static functions. (match_files): No longer recognize v_var specially; it is now handled via vertical table. (dir_tables_init): Register a vertical sys:var directive also via v_var function. (match_compat_fixup): New function. * txr.c (compat): Call match_compat_fixup. * tests/010/span-var.txr: New file. * txr.1: Documented.
Diffstat (limited to 'match.c')
-rw-r--r--match.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/match.c b/match.c
index de7e6186..1f10ab78 100644
--- a/match.c
+++ b/match.c
@@ -2316,6 +2316,39 @@ typedef val (*v_match_func)(match_files_ctx *cout);
val specline = first(spec); \
val first_spec = first(specline)
+static val v_var_compat(match_files_ctx *c)
+{
+ (void) c;
+ return decline_k;
+}
+
+static val v_var(match_files_ctx *c)
+{
+ spec_bind (specline, var_elem, c->spec);
+
+ if (!rest(specline)) {
+ val varsym = second(var_elem);
+ val modifiers = third(var_elem);
+ val modifier = first(modifiers);
+
+ if (consp(modifier)) {
+ match_files_ctx fc = mf_spec(*c, cons(modifiers, nil));
+ val data = c->data;
+
+ val ret = v_fun(&fc);
+
+ if (ret == next_spec_k) {
+ c->data = fc.data;
+ c->bindings = acons(varsym, ldiff(data, fc.data), fc.bindings);
+ }
+
+ return ret;
+ }
+ }
+
+ return decline_k;
+}
+
static val v_skip(match_files_ctx *c)
{
val self = lit("skip");
@@ -4662,11 +4695,11 @@ repeat_spec_same_data:
if (consp(first_spec) && !rest(specline)) {
val lfe_save = set_last_form_evaled(first_spec);
val sym = first(first_spec);
- val entry = gethash(v_directive_table, sym);
+ val entry;
- if (sym == var_s || sym == text_s) {
- /* It's actually a var or text; go to horizontal processing below */
- } else if (entry) {
+ if (sym == text_s) {
+ /* It's literal text; go to horizontal processing below */
+ } else if ((entry = gethash(v_directive_table, sym))) {
v_match_func vmf = coerce(v_match_func, cptr_get(entry));
val result = vmf(&c);
@@ -4985,7 +5018,7 @@ static void dir_tables_init(void)
sethash(v_directive_table, data_s, cptr(coerce(mem_t *, v_data)));
sethash(v_directive_table, name_s, cptr(coerce(mem_t *, v_name)));
sethash(v_directive_table, call_s, cptr(coerce(mem_t *, v_call)));
-
+ sethash(v_directive_table, var_s, cptr(coerce(mem_t *, v_var)));
sethash(h_directive_table, text_s, cptr(coerce(mem_t *, h_text)));
sethash(h_directive_table, var_s, cptr(coerce(mem_t *, h_var)));
sethash(h_directive_table, skip_s, cptr(coerce(mem_t *, h_skip)));
@@ -5062,3 +5095,9 @@ void match_init(void)
syms_init();
dir_tables_init();
}
+
+void match_compat_fixup(int compat_ver)
+{
+ if (compat_ver <= 272)
+ sethash(v_directive_table, var_s, cptr(coerce(mem_t *, v_var_compat)));
+}