From 109041fb2ea18893bea32a4743e995f0bc06d5aa Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 16 Mar 2018 20:39:47 -0700 Subject: 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. --- eval.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) 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), -- cgit v1.2.3