diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-10-23 21:56:57 -0400 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-10-23 21:56:57 -0400 |
commit | bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0 (patch) | |
tree | b62c87c230a2aace61851fe09040471a3157b1d2 | |
parent | 047116716e98766487f4a808ad53e097565dede2 (diff) | |
download | txr-bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0.tar.gz txr-bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0.tar.bz2 txr-bb8705bd33c1cfa89cf07573dc5c477bdae1d6d0.zip |
* 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.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | match.c | 39 | ||||
-rw-r--r-- | txr.1 | 20 |
3 files changed, 59 insertions, 9 deletions
@@ -1,5 +1,14 @@ 2011-10-23 Kaz Kylheku <kaz@kylheku.com> + * 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 <kaz@kylheku.com> + * match.c (h_skip): Bugfix: bad agument list in debugf call. 2011-10-22 Kaz Kylheku <kaz@kylheku.com> @@ -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); @@ -1711,6 +1719,31 @@ static val v_next(match_files_ctx c, match_files_ctx *cout) 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)); + return nil; + } } else if (nothrow) { if (str) { c.files = cons(cons(nothrow_k, str), c.files); @@ -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) @@ -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 |