diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-02-18 17:43:56 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-02-18 17:43:56 -0800 |
commit | d14ddd48c53f3d9ec960782c75f657a627456d22 (patch) | |
tree | f966df8f17c1a532a41ffa7c749edb0fd95418f5 | |
parent | 3b1e713d392d607a37e9f6d1520c4f9f584d014d (diff) | |
download | txr-d14ddd48c53f3d9ec960782c75f657a627456d22.tar.gz txr-d14ddd48c53f3d9ec960782c75f657a627456d22.tar.bz2 txr-d14ddd48c53f3d9ec960782c75f657a627456d22.zip |
Allow braced output variables to actually be arbitrary substitutions.
* eval.c (subst_vars): Treat the variable as an arbitrary
expression rather than just a symbol.
* match.c (subst_vars): Likewise.
* parser.y (o_var): Further simplification. The first item in
an output var is an expr and not an IDENT.
* txr.1: Updated.
* txr.vim: Likewise.
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | eval.c | 36 | ||||
-rw-r--r-- | match.c | 42 | ||||
-rw-r--r-- | parser.y | 9 | ||||
-rw-r--r-- | txr.1 | 17 | ||||
-rw-r--r-- | txr.vim | 2 |
6 files changed, 71 insertions, 51 deletions
@@ -1,5 +1,21 @@ 2012-02-18 Kaz Kylheku <kaz@kylheku.com> + Allow braced output variables to actually be arbitrary substitutions. + + * eval.c (subst_vars): Treat the variable as an arbitrary + expression rather than just a symbol. + + * match.c (subst_vars): Likewise. + + * parser.y (o_var): Further simplification. The first item in + an output var is an expr and not an IDENT. + + * txr.1: Updated. + + * txr.vim: Likewise. + +2012-02-18 Kaz Kylheku <kaz@kylheku.com> + * parser.y (o_var): Remove productions from grammar by using exprs_opt. 2012-02-17 Kaz Kylheku <kaz@kylheku.com> @@ -1118,29 +1118,23 @@ static val subst_vars(val forms, val env) val sym = first(form); if (sym == var_s) { - val sym = second(form); + val expr = second(form); val pat = third(form); val modifiers = fourth(form); - val pair = lookup_var(env, sym); - - if (pair) { - val str = cdr(pair); - - if (!stringp(str) && !listp(str)) - str = format(nil, lit("~a"), str, nao); - - if (pat) - forms = cons(str, cons(pat, rest(forms))); - else if (modifiers) - forms = cons(format_field(str, modifiers, nil, - curry_123_1(func_n3(eval), env, form)), - rest(forms)); - else - forms = cons(str, rest(forms)); - continue; - } - uw_throwf(query_error_s, lit("unbound variable ~a"), - sym, nao); + val str = eval(expr, env, form); + + if (!stringp(str) && !listp(str)) + str = format(nil, lit("~a"), str, nao); + + if (pat) + forms = cons(str, cons(pat, rest(forms))); + else if (modifiers) + forms = cons(format_field(str, modifiers, nil, + curry_123_1(func_n3(eval), env, form)), + rest(forms)); + else + forms = cons(str, rest(forms)); + continue; } else if (sym == quasi_s) { val nested = subst_vars(rest(form), env); list_collect_append(iter, nested); @@ -1316,37 +1316,31 @@ static val subst_vars(val spec, val bindings, val filter) val sym = first(elem); if (sym == var_s) { - val sym = second(elem); + val expr = second(elem); val pat = third(elem); val modifiers = fourth(elem); - val pair = assoc(sym, bindings); + val str = txeval(spec, expr, bindings); - if (pair) { - val str = cdr(pair); + if (!stringp(str) && !listp(str)) + str = format(nil, lit("~a"), str, nao); - if (!stringp(str) && !listp(str)) - str = format(nil, lit("~a"), str, nao); + if (pat) + spec = cons(pat, rest(spec)); - if (pat) - spec = cons(pat, rest(spec)); - - if (modifiers) { - spec = cons(format_field(str, modifiers, filter, - curry_123_2(func_n3(txeval), spec, bindings)), - rest(spec)); - } else { - if (listp(str)) - str = cat_str(mapcar(func_n1(tostringp), str), lit(" ")); - else - str = if3(stringp(str), str, tostringp(str)); - - spec = cons(filter_string(filter, str), rest(spec)); - } + if (modifiers) { + spec = cons(format_field(str, modifiers, filter, + curry_123_2(func_n3(txeval), spec, bindings)), + rest(spec)); + } else { + if (listp(str)) + str = cat_str(mapcar(func_n1(tostringp), str), lit(" ")); + else + str = if3(stringp(str), str, tostringp(str)); - continue; + spec = cons(filter_string(filter, str), rest(spec)); } - uw_throwf(query_error_s, lit("unbound variable ~a"), - sym, nao); + + continue; } else if (sym == quasi_s) { val nested = subst_vars(rest(elem), bindings, filter); list_collect_append(iter, nested); @@ -636,11 +636,10 @@ o_var : IDENT { $$ = list(var_s, intern(string_own($1), nil), nao); } | IDENT o_elem { $$ = list(var_s, intern(string_own($1), nil), $2, nao); } - | '{' IDENT exprs_opt '}' { $$ = list(var_s, intern(string_own($2), nil), - nil, $3, nao); } - | '{' IDENT exprs_opt '}' o_elem - { $$ = list(var_s, intern(string_own($2), nil), - $5, $3, nao); } + | '{' expr exprs_opt '}' + { $$ = list(var_s, $2, nil, $3, nao); } + | '{' expr exprs_opt '}' o_elem + { $$ = list(var_s, $2, $5, $3, nao); } | IDENT error { $$ = nil; yybadtoken(yychar, lit("variable spec")); } ; @@ -3334,6 +3334,8 @@ for the output clause. The syntax for this is @(NAME :filter <filterspec>}. The filter specification syntax is the same as in the output clause. See Output Filtering below. +.SS Output Variables: Indexing + Additional syntax is supported in output variables that is does not appear in pattern matching variables. @@ -3367,6 +3369,21 @@ The above produces the text "b,c" in a field 10 spaces wide. The [1..3] argument extracts a range of a; the "," argument specifies an alternate separator string, and 10 specifies the field width. +.SS Output Substitutions + +The brace syntax has another syntactic and semantic extension. In place +of the symbol, an expression may appear. The value of that expression +is substituted. + +Example: + + @(bind a "foo") + @(output) + @{`@a:` -10} + +Here, the quasiliteral expression `@a:` is evaluated, producing the string +"foo:". This string is printed right-adjusted in a 10 character field. + .SS The Repeat Directive The repeat directive is generates repeated text from a ``boilerplate'', @@ -108,7 +108,7 @@ syn match txr_ncomment ";.*" contained syn match txr_ident "[A-Za-z0-9!$%&*+\-<=>?\\^_~]\+" contained syn match txr_num "[+-]\?[0-9]\+" contained -syn region txr_bracevar matchgroup=Delimiter start="@[ \t]*[*]\?{" matchgroup=Delimiter end="}" contains=txr_num,txr_ident,txr_string,txr_dwim,txr_list,txr_regex,txr_quasilit,txr_chr +syn region txr_bracevar matchgroup=Delimiter start="@[ \t]*[*]\?{" matchgroup=Delimiter end="}" contains=txr_num,txr_meta,txr_metabkt,txr_ident,txr_string,txr_dwim,txr_list,txr_regex,txr_quasilit,txr_chr syn region txr_directive matchgroup=Delimiter start="@[ \t]*(" matchgroup=Delimiter end=")" contains=txr_keyword,txr_string,txr_list,txr_dwim,txr_metabkt,txr_meta,txr_quasilit,txr_num,txr_ident,txr_regex,txr_string,txr_variable,txr_chr,txr_hash,txr_ncomment |