summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-16 20:39:47 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-16 20:39:47 -0700
commit109041fb2ea18893bea32a4743e995f0bc06d5aa (patch)
treec8b456c6a8caa4864afe0634cd7cba9387009baa
parent7d94e4b2e24f22de9e12908ff610d4ac7823e1f9 (diff)
downloadtxr-109041fb2ea18893bea32a4743e995f0bc06d5aa.tar.gz
txr-109041fb2ea18893bea32a4743e995f0bc06d5aa.tar.bz2
txr-109041fb2ea18893bea32a4743e995f0bc06d5aa.zip
quasilit: expose access to field formatting.
This is the second round of changes in perparation for compiling the string quasiliterals special form. Having split format_fields into a lower level do_format_field and format_field, we now provide two functions which allow Lisp code to call do_format_field. The sys:fmt-simple function has fixed arguments for the field width/alignment, indexing/slicing, separator and plist. Any of them can be defaulted with nil. This function will be useful when the quasiliteral specifies modifiers that are simple literals or constant expressions. The sys:fmt-flex function takes a variable number of arguments, after the object and the plist. This function has to scan through the arguments and classify them by type: a string is a separator, an integer is a width and left/right alignment and so on. The compiler will use sys:flex when format field modifiers are present whose arguments contain expressions that get evaluated. * eval.c (fmt_simple, fmt_flex): New static functions. (eval_init): sys:fmt-simple and sys:fmt-flex registered.
-rw-r--r--eval.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 4cd431e2..bfcdae4d 100644
--- a/eval.c
+++ b/eval.c
@@ -2636,6 +2636,38 @@ val format_field(val obj, val modifier, val filter, val eval_fun)
return do_format_field(obj, n, sep, range_ix, plist, filter);
}
+static val fmt_simple(val obj, val n_in, val sep_in,
+ val range_ix, val plist)
+{
+ val n = if3(null(n_in), zero, n_in);
+ val sep = if3(null(sep_in), lit(" "), sep_in);
+ return do_format_field(obj, n, sep, range_ix, plist, nil);
+}
+
+static val fmt_flex(val obj, val plist, struct args *args)
+{
+ cnum ix = 0;
+ val n = zero, sep = lit(" ");
+ val range_ix = nil;
+
+ while (args_more(args, ix)) {
+ val arg = args_get(args, &ix);
+
+ if (integerp(arg)) {
+ n = arg;
+ } else if (stringp(arg)) {
+ sep = arg;
+ } else if (rangep(arg)) {
+ if (to(arg))
+ range_ix = arg;
+ else
+ range_ix = from(arg);
+ }
+ }
+
+ return do_format_field(obj, n, sep, range_ix, plist, nil);
+}
+
val subst_vars(val forms, val env, val filter)
{
list_collect_decl(out, iter);
@@ -6257,6 +6289,9 @@ void eval_init(void)
reg_fun(intern(lit("tprint"), user_package), func_n2o(tprint, 1));
reg_fun(intern(lit("display-width"), user_package), func_n1(display_width));
+ reg_fun(intern(lit("fmt-simple"), system_package), func_n5(fmt_simple));
+ reg_fun(intern(lit("fmt-flex"), system_package), func_n2v(fmt_flex));
+
reg_varl(user_package_s = intern(lit("user-package"), user_package_var),
user_package_var);
reg_varl(system_package_s = intern(lit("system-package"), user_package_var),