diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-03-16 20:39:47 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-03-16 20:39:47 -0700 |
commit | 109041fb2ea18893bea32a4743e995f0bc06d5aa (patch) | |
tree | c8b456c6a8caa4864afe0634cd7cba9387009baa | |
parent | 7d94e4b2e24f22de9e12908ff610d4ac7823e1f9 (diff) | |
download | txr-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.c | 35 |
1 files changed, 35 insertions, 0 deletions
@@ -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), |