diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-05-30 07:38:12 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-05-30 07:38:12 -0700 |
commit | c5134a9ddba4fd14703d506b0cccd51d823e013e (patch) | |
tree | 1d371e0060f94ceb8fc851872d580183542d9a5d | |
parent | 64ba99161ac55d77b09a72a0a64f2333ab7f0ffb (diff) | |
download | txr-c5134a9ddba4fd14703d506b0cccd51d823e013e.tar.gz txr-c5134a9ddba4fd14703d506b0cccd51d823e013e.tar.bz2 txr-c5134a9ddba4fd14703d506b0cccd51d823e013e.zip |
quasistrings: reduce consing.
Quasistrings compile to code that requires on the sys:fmt-join
function to glue strings together. Rewriting that function to
avoid converting its arguments from struct args * to a list.
* eval.c (fmt_join): Static function removed.
* lib.c (cat_str_measure, cat_str_append): more_p parameter
changed to int type, which better matches the C style Boolean
values it takes.
(fmt_join): New external function.
* lib.h: Declared.
* args.h (args_more_nozap, args_get_nozap): New inline
functions allowing multiple iterations over arguments without
making a copy.
-rw-r--r-- | args.h | 12 | ||||
-rw-r--r-- | eval.c | 5 | ||||
-rw-r--r-- | lib.c | 40 | ||||
-rw-r--r-- | lib.h | 1 |
4 files changed, 47 insertions, 11 deletions
@@ -130,6 +130,11 @@ INLINE int args_two_more(struct args *args, cnum index) cdr(args->list); } +INLINE int args_more_nozap(struct args *args, cnum index, val list) +{ + return list || index < args->fill; +} + void args_normalize_exact(struct args *args, cnum fill); void args_normalize_least(struct args *args, cnum fill); void args_normalize_fill(struct args *args, cnum minfill, cnum maxfill); @@ -173,6 +178,13 @@ INLINE val args_get(struct args *args, cnum *arg_index) return pop(&args->list); } +INLINE val args_get_nozap(struct args *args, cnum *arg_index, val *list) +{ + if (*arg_index < args->fill) + return args->arg[(*arg_index)++]; + return pop(list); +} + INLINE cnum args_count(struct args *args) { return args->fill + c_num(length_list(args->list)); @@ -2870,11 +2870,6 @@ static val fmt_flex(val obj, val plist, struct args *args) return do_format_field(fmt_tostring(obj), n, sep, range_ix, plist, nil); } -static val fmt_join(struct args *args) -{ - return cat_str(args_get_list(args), lit("")); -} - val subst_vars(val forms, val env, val filter) { list_collect_decl(out, iter); @@ -4101,7 +4101,7 @@ static void cat_str_init(struct cat_str *cs, val sep, wchar_t *onech) } } -static void cat_str_measure(struct cat_str *cs, val item, val more_p) +static void cat_str_measure(struct cat_str *cs, val item, int more_p) { if (!item) return; @@ -4143,7 +4143,7 @@ static void cat_str_alloc(struct cat_str *cs) cs->ptr = cs->str = chk_wmalloc(cs->total); } -static void cat_str_append(struct cat_str *cs, val item, val more_p) +static void cat_str_append(struct cat_str *cs, val item, int more_p) { if (!item) return; @@ -4176,12 +4176,12 @@ val cat_str(val list, val sep) cat_str_init(&cs, sep, onech); for (iter = list; iter != nil; iter = cdr(iter)) - cat_str_measure(&cs, car(iter), cdr(iter)); + cat_str_measure(&cs, car(iter), cdr(iter) != nil); cat_str_alloc(&cs); for (iter = list; iter != nil; iter = cdr(iter)) - cat_str_append(&cs, car(iter), cdr(iter)); + cat_str_append(&cs, car(iter), cdr(iter) != nil); return cat_str_get(&cs); } @@ -4197,7 +4197,7 @@ static val vscat(val sep, va_list vl1, va_list vl2) for (item = va_arg(vl1, val); item != nao; item = next) { next = va_arg(vl1, val); - cat_str_measure(&cs, item, tnil(next != nao)); + cat_str_measure(&cs, item, next != nao); } cat_str_alloc(&cs); @@ -4205,7 +4205,7 @@ static val vscat(val sep, va_list vl1, va_list vl2) for (item = va_arg(vl2, val); item != nao; item = next) { next = va_arg(vl2, val); - cat_str_append(&cs, item, tnil(next != nao)); + cat_str_append(&cs, item, next != nao); } return cat_str_get(&cs); @@ -4223,6 +4223,34 @@ val scat(val sep, ...) return ret; } +val fmt_join(struct args *args) +{ + cnum index; + val iter; + int more; + struct cat_str cs; + + cat_str_init(&cs, nil, 0); + + for (index = 0, iter = args->list, more = args_more_nozap(args, index, iter); + more;) + { + val item = args_get_nozap(args, &index, &iter); + cat_str_measure(&cs, item, more = args_more_nozap(args, index, iter)); + } + + cat_str_alloc(&cs); + + for (index = 0, iter = args->list, more = args_more_nozap(args, index, iter); + more;) + { + val item = args_get_nozap(args, &index, &iter); + cat_str_append(&cs, item, more = args_more_nozap(args, index, iter)); + } + + return cat_str_get(&cs); +} + val split_str_keep(val str, val sep, val keep_sep) { keep_sep = default_null_arg(keep_sep); @@ -852,6 +852,7 @@ val replace_str(val str_in, val items, val from, val to); val sub_str(val str_in, val from_num, val to_num); val cat_str(val list, val sep); val scat(val sep, ...); +val fmt_join(struct args *args); val split_str(val str, val sep); val split_str_keep(val str, val sep, val keep_sep); val spl(val sep, val arg1, val arg2); |