diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-04-27 22:04:05 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-04-27 22:04:05 -0700 |
commit | 10fc6e23661ad004591936b5c28b9cb17e596b8f (patch) | |
tree | 9e20e5828dc54d20d4e9f5f2372bfa348fbae381 /match.c | |
parent | 7afbcc19bef877560f096c02e63b22f9f650b74e (diff) | |
download | txr-10fc6e23661ad004591936b5c28b9cb17e596b8f.tar.gz txr-10fc6e23661ad004591936b5c28b9cb17e596b8f.tar.bz2 txr-10fc6e23661ad004591936b5c28b9cb17e596b8f.zip |
Simple indirection on pattern functions: @(call).
* eval.h (call_s): Declared.
* match.c (h_call, v_call): New static function.
(dir_tables_init): Register v_call in v_directive_table
under call symbol. Likewise h_call in h_directive_table.
* txr.1: Documented.
Diffstat (limited to 'match.c')
-rw-r--r-- | match.c | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -1239,6 +1239,42 @@ static match_files_ctx mf_all(val spec, val files, val bindings, static val v_fun(match_files_ctx *c); +static val h_call(match_line_ctx *c) +{ + val saved_specline = c->specline; + val elem = first(saved_specline); + val args = rest(elem); + val funexpr = first(args); + val funval = txeval(c->specline, funexpr, c->bindings); + val argexprs = rest(args); + val call = cons(funval, argexprs); + val new_specline = cons(call, nil); + val ret; + + c->specline = new_specline; + + ret = h_fun(c); + + c->specline = saved_specline; + + if (ret == decline_k) { + val spec = cons(new_specline, nil); + match_files_ctx vc = mf_all(spec, nil, c->bindings, nil, c->file); + val vresult = v_fun(&vc); + + if (vresult == next_spec_k) { + c->bindings = vc.bindings; + return vresult; + } else if (vresult == decline_k) { + sem_error(elem, lit("call: function ~s not found"), funval, nao); + } + + return vresult; + } + + return ret; +} + static val do_match_line(match_line_ctx *c) { val lfe_save = set_last_form_evaled(nil); @@ -3863,6 +3899,27 @@ static val v_name(match_files_ctx *c) return next_spec_k; } +static val v_call(match_files_ctx *c) +{ + spec_bind (specline, first_spec, c->spec); + val exprs = rest(first_spec); + val funexpr = car(exprs); + val funval = txeval(specline, funexpr, c->bindings); + val argexprs = cdr(exprs); + val call = cons(funval, argexprs); + val spec = cons(cons(call, nil), nil); + match_files_ctx ctx = mf_spec_bindings(*c, spec, c->bindings); + val ret = v_fun(&ctx); + + if (ret == nil) + return nil; + + if (ret == decline_k) + sem_error(nil, lit("call: function ~s not found"), funval, nao); + + return cons(ctx.bindings, if3(ctx.data, cons(ctx.data, ctx.data_lineno), t)); +} + static val h_do(match_line_ctx *c) { val elem = first(c->specline); @@ -4216,6 +4273,7 @@ static void dir_tables_init(void) sethash(v_directive_table, line_s, cptr(coerce(mem_t *, v_line))); 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(h_directive_table, text_s, cptr(coerce(mem_t *, h_text))); sethash(h_directive_table, var_s, cptr(coerce(mem_t *, h_var))); @@ -4247,6 +4305,7 @@ static void dir_tables_init(void) sethash(h_directive_table, line_s, cptr(coerce(mem_t *, hv_trampoline))); sethash(h_directive_table, data_s, cptr(coerce(mem_t *, hv_trampoline))); sethash(h_directive_table, name_s, cptr(coerce(mem_t *, hv_trampoline))); + sethash(h_directive_table, call_s, cptr(coerce(mem_t *, h_call))); sethash(non_matching_directive_table, block_s, t); sethash(non_matching_directive_table, accept_s, t); |