summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-16 06:25:54 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-16 06:25:54 -0700
commitab00af8cc82fc392811b9da08b7646ffd33f67cd (patch)
treec5df63abeef87be94f4984a575404abe52902fc0 /eval.c
parent088cc06dcf434b700da425b2f18b2a9a0ea46889 (diff)
downloadtxr-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.c101
1 files changed, 55 insertions, 46 deletions
diff --git a/eval.c b/eval.c
index 6cfd4a86..4cd431e2 100644
--- a/eval.c
+++ b/eval.c
@@ -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)
{