diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-03-16 06:25:54 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-03-16 06:25:54 -0700 |
commit | ab00af8cc82fc392811b9da08b7646ffd33f67cd (patch) | |
tree | c5df63abeef87be94f4984a575404abe52902fc0 /eval.c | |
parent | 088cc06dcf434b700da425b2f18b2a9a0ea46889 (diff) | |
download | txr-ab00af8cc82fc392811b9da08b7646ffd33f67cd.tar.gz txr-ab00af8cc82fc392811b9da08b7646ffd33f67cd.tar.bz2 txr-ab00af8cc82fc392811b9da08b7646ffd33f67cd.zip |
quasilit: split format_field into two functions.
The objective of this work is to isolate the field-formatting
logic so we can target it in the compiler.
Currently, the sys:quasi special operator relies on calling
subst_vars, which calls format_field. Both subst_vars
and format_field perform dynamic evaluation, requiring
an environment. In the compiler, this will be replaced by
macro-generated logic; but we would like to obtain the use of
the lower-level field formatting as a pure function.
* eval.c (do_format_field): New static function. Does the
field formatting previously done in format_field. Also
performs the indexing on the object implied by the numeric
or range modifier; but the range or index is already
computed and comes in as a parameter.
(format_field): Perform the modifier parsing only, requiring
the dynamic evaluations via eval_fun, and then call
do_format_field on the extracted data. The range indexing
on the input sequence is no longer done during the parsing of
the modifiers. That unfortunately changes some behaviors that
are possible but are fortunately obscure and undocumented.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 101 |
1 files changed, 55 insertions, 46 deletions
@@ -2531,55 +2531,20 @@ static val op_handler_bind(val form, val env) return result; } -val format_field(val obj, val modifier, val filter, val eval_fun) +static val do_format_field(val obj, val n, val sep, + val range_ix, val plist, + val filter) { - val n = zero, sep = lit(" "); - val plist = nil; val str; - for (; modifier; pop(&modifier)) { - val item = first(modifier); - if (regexp(item)) { - uw_throw(query_error_s, lit("bad field format: regex modifier in output var")); - } else if (keywordp(item)) { - plist = modifier; - break; - } else if ((!opt_compat || opt_compat > 128) && - consp(item) && car(item) == expr_s) - { - item = cadr(item); - goto eval; - } else if (consp(item) && car(item) == dwim_s) { - val arg_expr = second(item); - - if (consp(arg_expr) && car(arg_expr) == range_s) { - val from = funcall1(eval_fun, second(arg_expr)); - val to = funcall1(eval_fun, third(arg_expr)); - - obj = sub(obj, from, to); - } else { - val arg = funcall1(eval_fun, arg_expr); - if (integerp(arg)) { - obj = ref(obj, arg); - } else if (rangep(arg)) { - obj = sub(obj, from(arg), to(arg)); - } else { - uw_throwf(query_error_s, - lit("bad field format: index ~s expected to be integer or range"), - arg, nao); - } - } - } else eval: { - val v = funcall1(eval_fun, item); - if (fixnump(v)) - n = v; - else if (stringp(v)) - sep = v; - else - uw_throwf(query_error_s, - lit("bad field format: modifier ~s expected to be fixnum or string"), - v, nao); - } + if (integerp(range_ix)) { + obj = ref(obj, range_ix); + } else if (rangep(range_ix)) { + obj = sub(obj, from(range_ix), to(range_ix)); + } else if (range_ix) { + uw_throwf(query_error_s, + lit("bad field format: index ~s expected to be integer or range"), + range_ix, nao); } str = if3(stringp(obj), @@ -2626,6 +2591,50 @@ val format_field(val obj, val modifier, val filter, val eval_fun) } } +val format_field(val obj, val modifier, val filter, val eval_fun) +{ + val n = zero, sep = lit(" "); + val plist = nil; + val range_ix = nil; + + for (; modifier; pop(&modifier)) { + val item = first(modifier); + if (regexp(item)) { + uw_throw(query_error_s, lit("bad field format: regex modifier in output var")); + } else if (keywordp(item)) { + plist = modifier; + break; + } else if ((!opt_compat || opt_compat > 128) && + consp(item) && car(item) == expr_s) + { + item = cadr(item); + goto eval; + } else if (consp(item) && car(item) == dwim_s) { + val arg_expr = second(item); + + if (consp(arg_expr) && car(arg_expr) == range_s) { + val from = funcall1(eval_fun, second(arg_expr)); + val to = funcall1(eval_fun, third(arg_expr)); + + range_ix = rcons(from, to); + } else { + range_ix = funcall1(eval_fun, arg_expr); + } + } else eval: { + val v = funcall1(eval_fun, item); + if (fixnump(v)) + n = v; + else if (stringp(v)) + sep = v; + else + uw_throwf(query_error_s, + lit("bad field format: modifier ~s expected to be fixnum or string"), + v, nao); + } + } + + return do_format_field(obj, n, sep, range_ix, plist, filter); +} val subst_vars(val forms, val env, val filter) { |