From bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 23 Oct 2011 21:56:57 -0400 Subject: * match.c (list_k, string_k): New keyword symbol variables. (v_next): Implement :list and :string keywords. (syms_init): New keyword variables initialized. NOTE: the :var keyword is deprecated. * txr.1: Documented :list and :string. --- ChangeLog | 9 +++++++++ match.c | 39 +++++++++++++++++++++++++++++++++++++-- txr.1 | 20 +++++++++++++------- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f3f9e76..bc97d097 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-10-23 Kaz Kylheku + + * match.c (list_k, string_k): New keyword symbol variables. + (v_next): Implement :list and :string keywords. + (syms_init): New keyword variables initialized. + NOTE: the :var keyword is deprecated. + + * txr.1: Documented :list and :string. + 2011-10-23 Kaz Kylheku * match.c (h_skip): Bugfix: bad agument list in debugf call. diff --git a/match.c b/match.c index 06145609..aaab3bc2 100644 --- a/match.c +++ b/match.c @@ -53,7 +53,7 @@ val mingap_k, maxgap_k, gap_k, mintimes_k, maxtimes_k, times_k; val lines_k, chars_k; val choose_s, longest_k, shortest_k, greedy_k; val vars_k; -val append_k, into_k, var_k; +val append_k, into_k, var_k, list_k, string_k; static val h_directive_table, v_directive_table; @@ -1685,13 +1685,21 @@ static val v_next(match_files_ctx c, match_files_ctx *cout) { val alist = improper_plist_to_alist(args, list(nothrow_k, nao)); val from_var = cdr(assoc(alist, var_k)); + val list_expr = cdr(assoc(alist, list_k)); + val string_expr = cdr(assoc(alist, string_k)); val nothrow = cdr(assoc(alist, nothrow_k)); val eval = eval_form(spec_linenum, source, c.bindings); val str = cdr(eval); - if (!from_var && !source) + if (!from_var && !source && !string_expr && !list_expr) sem_error(spec_linenum, lit("next: source required before keyword arguments"), nao); + if ((from_var && string_expr) || (string_expr && list_expr) || + (from_var && list_expr)) + { + sem_error(spec_linenum, lit("next: only one of :var, :list or :string can be specified"), nao); + } + if (from_var) { val existing = assoc(c.bindings, from_var); @@ -1706,6 +1714,31 @@ static val v_next(match_files_ctx c, match_files_ctx *cout) match_files(mf_file_data(c, lit("var"), flatten(cdr(existing)), num(1)))); + if (success) + return cons(new_bindings, + if3(c.data, cons(c.data, c.data_lineno), t)); + return nil; + } + } else if (list_expr) { + val list_val = cdr(eval_form(spec_linenum, list_expr, c.bindings)); + cons_bind (new_bindings, success, + match_files(mf_file_data(c, lit("var"), + flatten(list_val), num(1)))); + + if (success) + return cons(new_bindings, + if3(c.data, cons(c.data, c.data_lineno), t)); + return nil; + } else if (string_expr) { + val str_val = cdr(eval_form(spec_linenum, string_expr, c.bindings)); + if (!stringp(str_val)) + sem_error(spec_linenum, lit(":string arg ~s evaluated to non-string ~s"), string_expr, str_val, nao); + + { + cons_bind (new_bindings, success, + match_files(mf_file_data(c, lit("var"), + split_str(str_val, lit("\n")), num(1)))); + if (success) return cons(new_bindings, if3(c.data, cons(c.data, c.data_lineno), t)); @@ -2769,6 +2802,8 @@ static void syms_init(void) append_k = intern(lit("append"), keyword_package); into_k = intern(lit("into"), keyword_package); var_k = intern(lit("var"), keyword_package); + list_k = intern(lit("list"), keyword_package); + string_k = intern(lit("string"), keyword_package); } static void dir_tables_init(void) diff --git a/txr.1 b/txr.1 index 49ea719c..79a49a68 100644 --- a/txr.1 +++ b/txr.1 @@ -1090,7 +1090,8 @@ with, or without arguments: @(next SOURCE) @(next SOURCE :nothrow) @(next :args) - @(next :var SYMBOL) + @(next :list EXPR) + @(next :string EXPR) The lone @(next) without arguments switches to the next file in the argument list which was passed to the @@ -1126,10 +1127,16 @@ open the input source named by that argument. If the very first directive of a q avoids opening the first input source, but it does open the input source for any other directive, even one which does not consume any data. -The variant @(next :var SYMBOL) treats a the variable named by SYMBOL -as a source of text. The contents of the variable are flattened to a list as if -by the @(flatten) directive (but without modifying the variable). -The resulting list is treated as if it were the lines of a text file. +The syntax @(next :list EXPR) treats the expression as a source of +text. The value of the expression is flattened to a list in a way similar +to the @(flatten) directive. The resulting list is treated as if it were the +lines of a text file: each element of the list is a line. If the lines +happen contain embedded newline characters, they are a visible constituent +of the line, and do not act as line separators. + +The syntax @(next :string EXPR) treats the expression as a source of +text. The value of the expression must be a string. Newlines in the string are +interpreted as line terminators. Note that "remainder of the query" refers to the subquery in which the next directive appears, not necessarily the entire query. @@ -1142,8 +1149,7 @@ previous file again. @(some) @(next "foo.txt") xyz@suffix - @(end) - abc + @(end) abc However, if the @(some) subquery successfully matched "xyz@suffix" within the file foo.text, there is now a binding for the suffix variable, which -- cgit v1.2.3