summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
...
* unique: covert to seq_build.Kaz Kylheku2024-03-021-3/+4
| | | | | | * lib.c (unique): Build output using seq_build_t, rather than consing up a list which is then converted to the desired sequence type.
* zip: make more generic.Kaz Kylheku2024-03-011-39/+0
| | | | | | | | | | | | | | | | * lib.c (do_pa_12_1_v, pa_12_1_v): Static functions removed. (transposev, transpose): Functions removed. * lib.c (transposev, transpose): Declarations removed. * eval.c (join_f): New global variable. (zip_fun, zipv, transpose): New static functions. (eval_init): gc-protect join_f, and initialize it. Registration of zip intrinsic goes to zipv rather than transposev. sys:fmt-join and join registered with help of global join_f rather than local. * tests/012/seq.tl: New zip test cases.
* partition, split, split*: iter used for indicesKaz Kylheku2024-02-291-10/+14
| | | | | | | | | | | | | | | | | | * lib.c (partition_func, split_func, split_star_func): Indices passed through lazy cons are now iterator, rather than a sequence accessed via car and cdr, which is inefficient for nonlists. (partition-split-common): Use iter-begin to convert indices to iterator, which becomes the cdr field of the lazy cons. * txr.1: Update documentation for these functions to clarify that the second argument is a sequence. The inaccurate text claiming that "if the second argument is an atom other than a function" is rewritten. This doesn't describe the behavior that is implemented, where the test applied is seqp, not atom. The indices can be a vector of integers, which is an atom.
* partition-if: use seq_build for accumulating partitions.Kaz Kylheku2024-02-281-4/+6
| | | | | * lib.c (partition_if_func): Instead of list_collect_decl and make_like, use seq_build.
* partition-by: replace sequence traversal with iter.Kaz Kylheku2024-02-281-10/+13
| | | | | | | | * lib.c (partition_by_func): The seq object is now an iter object: use iter_more, iter_item and iter_step rather than non-null test, car and cdr. (partition_by): Obtain iterator for sequence using iter_begin, and use that in its place.
* partition-by: replace tuple accumulation with seq_build.Kaz Kylheku2024-02-281-6/+7
| | | | | * lib.c (partition_by_func): Use seq_build instead of list_collect_decl and make_like.
* seq_build: seq_pend must be nondestructive for lists.Kaz Kylheku2024-02-281-1/+17
| | | | | | | | | | | | | | | | | | | | Let's have both a seq_pend and seq_nconc, where seq_nconc can reuse the pieces of list passed to it. * lib.h (struct seq_build_ops): New member, nconc. (seq_build_ops_init): Add nconc parameter and initializer. (seq_nconc): Function declared. * lib.c (seq_build_list_pend): Switch to list_collect_append, otherwise mappend behaves destructively. (seq_build_list_nconc): New function. (sb_vec_ops, sb_str_ops, sb_buf_ops, sb_struct_ops, sb_carray_ops): Use seq_build_generic_pend for nconc operation. (sb_list_ops): Use new seq_build_list_nconc for nconc operation. (sb_finished_ops): Use null pointer for nconc operation. (seq_nconc): New function.
* seq_build: convert list buiding to list_collect.Kaz Kylheku2024-02-281-68/+9
| | | | | | | | | | | | | | | | | | | | | | | | | We want to use the list_collect functions for consistency. For instance, these functions allow an atom to be added to an improper list if the terminating atom is a sequence. (append '(1 . "abc") "d") yields (1 . "abcd"). * lib.h (struct seq_build): New member, tail. * lib.c (seq_build_list_add): Use list_collect. (seq_build_list_pend): Use list_collect_nconc. (seq_build_list_finish): Nothing to do here, except call seq_build_convert_to_finished since bu->obj is the head of the list at all times now. (seq_build_improper_add, seq_build_improper_pend): Functions removed. (sb_improper_ops): Structure removed. (seq_build_convert_to_improper): Function removed. (seq_build_convert_to_list): Different strategy needed here now. The list just goes into bu->obj, and we have to set up the tail to either point to the last cons cell's cdr, or else to bu->obj if the list is empty. (seq_build_init): Initialize bu->tail in the three cases that set up list collection.
* seq_build: whitespace.Kaz Kylheku2024-02-281-1/+1
| | | | * lib.c (sb_vec_ops): fix indentation.
* seq_build: remove unnecessary convert calls.Kaz Kylheku2024-02-281-2/+0
| | | | | | * lib.c (seq_build_struct_finish, seq_build_carray_finish): Do not call seq_build_convert_to_finished, since seq_build_list_finish has already done that.
* seq_build: remove one finish function.Kaz Kylheku2024-02-281-6/+1
| | | | | | | | * lib.c (seq_build_improper_finish): Function removed. (sb_improper_ops): Replace seq_build_improper_finish with null pointer. The seq_finish function checks for null and avoids calling, so we don't need the noop implementation.
* seq_build: safeguard against adding to finished object.Kaz Kylheku2024-02-281-0/+14
| | | | | | | | * lib.c (seq_build_convert_to_finished): New function. (seq_build_list_finish): call seq_build_convert_to_finished. (sb_finished_ops): New static struct. All operations except mark are null pointers so this will crash if used.
* mapcar, mappend: switch to seq_build.Kaz Kylheku2024-02-271-4/+16
| | | | | | | | | | | | | | * lib.c (mapcar): Implement with seq_iter and seq_build, rather than relying on mapcar_listout and make_like. (mappend): Replace list_collect_decl and make_like with seq_build. * eval.c (map_common): Replace list_collect_decl and make_like with seq_build. The collect_fn is now a pointer to either seq_add or seq_pend rather than list_collect or list_collect_append. (mapcarv, mappendv): Pass seq_add and seq_pend to map_common, rather than list_collect and list_collect_append.
* seq_build: support improper lists.Kaz Kylheku2024-02-271-1/+53
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To be useful for some operations, the seq_build framework must handle the pend operation on lists specially. The appended piece must only be treated as a sequence if it is a cons. Moreover, if it is an atom, or of it is an improper list, then the list terminates. Subsequent add and pend operations must fail. The atom must appear as the terminator. We meet these objectives by switching the object's operations, sb_list_ops, to a new set of operations, sb_improper_ops. * lib.c (seq_build_list_pend): New static function. This individually adds all items from the input list, until it hits a terminating atom. If the atom isn't nil, it converts the seq_build_t object to improper operations. (seq_build_improper_add, seq_build_improper_pend): New static functions. These throw an error: adding anything to an improper list is impossible. (seq_build_improper_finish): New function, which does nothing: the improper list is finished already. (sb_list_ops): Use the seq_build_list_pend operation rather than the generic one. (sb_improper_ops): New static structure. (seq_build_convert_to_improper): New static function. Finishes the list, giving it the specified terminating atom, and then switches to sb_improper_ops so that adding is no longer possible.
* tuples: convert tuple generation to seq_build.Kaz Kylheku2024-02-271-4/+7
| | | | | | | | | | * lib.c (tuples_func): Replace list accumulation with make_like with seq_build. * tests/012/seq.tl: Fix one test case here which no longer errors out. It produces a tuple which is not a string, due to the inclusion of a non-character object.
* seq_build: fix: incompatible items must create list.Kaz Kylheku2024-02-271-12/+30
| | | | | | | | | | | | | | | | | | | | | In the make_like function, the list is converted to string or buffer if the first element of the list is a character, or integer. We need similar logic in seq_build. We can make it better. When any item is added which is incompatible, we can convert what we have so far to a list, change the seq_build type to list, and keep going. * lib.c (seq_build_convert_to_list): New static function. (seq_build_str_add, seq_build_buf_add): If the item is incompatible, convert the string or buffer to a list and pass to seq_build_convert_to_list. Then call bu->ops->add to add the item, now as a list. (seq_build_buf_pend): Function removed. (sb_buf_ops): Use the seq_build_generic_pend function for the pend operation. This is because we have to check each item one by one; we cannot use replace_buf.
* seq_build: struct/carray bugfix.Kaz Kylheku2024-02-271-3/+4
| | | | | | | * lib.c (seq_build_struct_finish, seq_build_carray_finish): These functions are still wrongly assuming that the list is finished by nreverse. We intead call seq_build_list_finish for that, which puts the list back into bu->obj.
* seq_build: put self name into structure.Kaz Kylheku2024-02-271-15/+16
| | | | | | | | | | | | | | | * lib.h (struct seq_build): New member, self. (struct seq_build_ops): Remove self parameter from pend function. (seq_build_init, seq_pend): Declarations updated. * lib.c (seq_build_generic_pend): Drop self parameter, take the value from structure. (seq_build_buf_pend): Drop self parameter. (seq_build_init): New self parameter. Pass recursively. (seq_pend): Self parameter dropped. (rem_impl, rem_if_impl, keep_keys_if, separate, separate_keys): Pass self to seq_build_init.
* seq_build: build lists in order using tail pointer.Kaz Kylheku2024-02-271-2/+19
| | | | | | | | | | * lib.c (seq_build_list_add, seq_build_list_finish): We use the trick that bu->obj (if not nil) points to the tail cons cell of the list being built, and the cdr of that tail always points back to the head. To finish the list, all we do is nil out that head pointer, so the list is properly terminated, and then plan the head as bu->obj.
* separate-keys: rework using seq_buildKaz Kylheku2024-02-271-62/+13
| | | | * lib.c (separate_keys): Rewrite using seq_info and seq_build.
* separate: rework using seq_build.Kaz Kylheku2024-02-271-75/+13
| | | | | * lib.c (separate): switch statement with type-specific coding replaced with generic sequence iteration and building.
* seq_build: allow initialization from iterator.Kaz Kylheku2024-02-271-0/+6
| | | | | | * lib.c (seq_build_init): Replicate a feature of make_like: if the reference object is an iterator, then we recurse: we initialize according to the object it is iterating.
* keep-keys-if: rework with generic sequence processing.Kaz Kylheku2024-02-261-56/+12
| | | | | * lib.c (keep_keys_if): Replace with generic sequence iteration and building.
* New sequence building framework.Kaz Kylheku2024-02-261-123/+207
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Just as the "seq_iter" iterators help to condense the code for iterating any kind of sequence, "seq_builder" objects solve the problem of producing a sequence of the same kind as an input sequence. Until now, two approaches have been taken for this. One was to have separately coded cases: code iterating over a string building up a string, and so on. The other has been to produce a list, which is then coerced to the right sequence type using make_like. The approach introduced here is similar to using make_like, but without wastefully consing up a temporary list. The remove-if, remqual, remql, remq and keep-if functions are retargetted to this new abstraction. * lib.h (struct seq_build, seq_build_t): New struct type. (struct seq_build_ops): New struct type. (seq_build_ops_init): New macro. (seq_build_init, seq_add, seq_pend, seq_finish): Functions declared. * lib.c (seq_build_generic_pend, seq_build_obj_mark, seq_build_struct_mark, seq_build_carray_mark, seq_build_vec_add, seq_build_str_add, seq_build_buf_add, seq_build_buf_pend, seq_build_buf_finish, seq_build_list_add, seq_build_list_finish, seq_build_struct_finish, seq_build_carray_finish): New static functions. (sb_vec_ops, sb_str_ops, sb_buf_ops, sb_struct_ops, sb_carray_ops, sb_list_ops): New static structs. (seq_build_init, seq_add, seq_pend, seq_finish): New functions. (rem_impl, rem_if_impl): Reworked in terms of seq_iter and seq_build, becoming much shorter, and handling all iterable objects.
* keep-if: don't report as remove-if in errors.Kaz Kylheku2024-02-261-3/+7
| | | | | | | * lib.c (rem_if_impl): New static function, based on renaming remove_if, and adding a self parameter. (remove_if): Now wrapper around rem_if_impl. (keep_if): Retarget to rem_if_impl, passing "keep-if" name.
* New function: cons-count.Kaz Kylheku2024-02-091-0/+19
| | | | | | | | | | | | | * eval.c (eval_init): Register cons-count intrinsic. * lib.c (cons_count_rec): New static function. (cons_count): New function. * lib.h (cons_count): Declared. * tests/012/cons.tl: New tests. * txr.1: Documented.
* New function: cons-find.Kaz Kylheku2024-02-091-0/+17
| | | | | | | | | | | | | | | | | * eval.c (cons_find): Static function removed; a new one is implemented in lib.c. (eval_init): Register cons-find intrinsic. * lib.c (cons_find_rec): New static function. (cons_find): New function. * lib.h (cons_find): Declared. * tests/012/cons.tl: New file. * txr.1: Documented cons-find together with tree-find. Document that tree-find's test-fun argument is optional, defaulting to equal.
* New function: hist-sort-by.Kaz Kylheku2024-02-021-2/+7
| | | | | | | | | | | | | * eval.c (eval_init): Register hist-sort-by intrinsic. * lib.c (hist_sort_by): New function. (hist_sort): Wrapper for hist_sort_by now. * lib.h (hist_sort_by): Declared. * tests/012/sort.tl: Tests. * txr.1: Documented.
* We need a length-< special method.Kaz Kylheku2024-01-191-1/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Structure objects can be used to implement lazy structures such as sequences. It is undesirable to take the length of a lazy sequence because it forces all of its elements to exist. Moreover, if the sequence is infinite, it is impossible. There are situations in which it is only necessary to know whether the length is less than a certain bound, and for that we have the length-< function. That works on infinite sequence such as lazy lists, requiring them to be forced only so far as to determine the truth value of the test. We need objects that implement lazy sequences to work with this function. * struct.h (enum special_slot): New member length_lt_m. * lib.h (length_lt_s): Symbol variable declared. * struct.c (special_sym): New entry in this table, associating the length_lt_m enum with the length_lt_s symbol variable. * lib.c (length_lt_s): Symbol variable defined. (length_lt): Handle COBJ objects that are structures. we test whether they have a length-< method, or else length method. If they don't have either, we throw. We don't fall back on the default case for objects that don't have a length-< method, because the diagnostic won't be good if they don't have a length method either; the programmer will be informed that the length function couldn't find a length method, without mentioning that it was actually length-< that is being used. * eval.c (eval_init): Register length-< using the length_lt_s symbol variable rather than using intern. * txr.1: Documented. * tests/012/oop-seq.tl: New tests.
* Copyright year bump 2024.Kaz Kylheku2024-01-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, alloca.h, args.c, args.h, arith.c, arith.h, autoload.c, autoload.h, buf.c, buf.h, cadr.c, cadr.h, chksum.c, chksum.h, chksums/crc32.c, chksums/crc32.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, ffi.c, ffi.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, gzio.c, gzio.h, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, psquare.h, rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, socket.c, socket.h, stdlib/arith-each.tl, stdlib/asm.tl, stdlib/awk.tl, stdlib/build.tl, stdlib/cadr.tl, stdlib/compiler.tl, stdlib/constfun.tl, stdlib/conv.tl, stdlib/copy-file.tl, stdlib/csort.tl, stdlib/debugger.tl, stdlib/defset.tl, stdlib/doloop.tl, stdlib/each-prod.tl, stdlib/error.tl, stdlib/except.tl, stdlib/expander-let.tl, stdlib/ffi.tl, stdlib/getopts.tl, stdlib/getput.tl, stdlib/glob.tl, stdlib/hash.tl, stdlib/ifa.tl, stdlib/keyparams.tl, stdlib/load-args.tl, stdlib/match.tl, stdlib/op.tl, stdlib/optimize.tl, stdlib/package.tl, stdlib/param.tl, stdlib/path-test.tl, stdlib/pic.tl, stdlib/place.tl, stdlib/pmac.tl, stdlib/quips.tl, stdlib/save-exe.tl, stdlib/socket.tl, stdlib/stream-wrap.tl, stdlib/struct.tl, stdlib/tagbody.tl, stdlib/termios.tl, stdlib/trace.tl, stdlib/txr-case.tl, stdlib/type.tl, stdlib/vm-param.tl, stdlib/with-resources.tl, stdlib/with-stream.tl, stdlib/yield.tl, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, time.c, time.h, tree.c, tree.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h, win/cleansvg.txr, y.tab.c.shipped: Copyright year bumped to 2024.
* lib: avoid realloc with zero size.Kaz Kylheku2024-01-161-3/+13
| | | | | | | | | | | | | I spotted in the N3096 draft of ISO C (April 2023) that a zero size in realloc is no longer defined behavior, like it used to be. I don't know exactly when it changed; in C99 it is not mentioned. We call realloc only in one place, so we can defend agains this. * lib.c (chk_realloc): If the new size is zero, we implement the C99 and older semantics: deallocate the object, and then behave like malloc(0). In other cases, we use realloc.
* gc: bug in sub-str on lazy string argument.Kaz Kylheku2024-01-061-0/+1
| | | | | | | | | | | This showed up as an intermittent segfault on OpenBSD of the test case tests/006/freeform-5.txr, reproducible quite often, around 30% to 60%. This was with gcc 4.2.1. * lib.c (lazy_sub_str): We need a gc_hint here on the prefix hend in pfxcopy. The garbage collector is scavenging that object, not seeing that we planted it into a malloced structure.
* iter_begin: gc problem.Kaz Kylheku2024-01-011-0/+2
| | | | | | | | | | Also affects seq_begin. * lib.c (seq_begin, iter_begin): We must gc_protect the incoming obj also, not only the iter. Both these pointers are in the seq_info_t structure which is no longer used at the time the iterator is being allocated by the call to cobj, and so may be prematurely garbage collected.
* print: print/read consistency problem with rcons.Kaz Kylheku2023-12-081-1/+2
| | | | | | | | | | * lib.c (obj_print_impl): Do not print (rcons X Y) as X..Y if X looks like (rcons ...). This causes the problem that (rcons (rcons 1 2) 3) prints as 1..2..3, a notation which unambiguously means (rcons 1 (rcons 2 3)). * tests/012/syntax.tl: New test cases.
* oop: allow del on struct sequences.Kaz Kylheku2023-11-151-3/+0
| | | | | | | | | | * lib.c (dwim_del): Remove check against structures from OBJ case; we just let this pass through to the logic that invokes replace. * tests/012/aseq.tl: New test cases. * txr.1: Document how del works on a [obj index] place.
* dwim: correction to error diagnostic.Kaz Kylheku2023-11-151-1/+1
| | | | | | | * lib.c (dwim_set): The "not a place" diagnostic applies not only in situations when the object is a list; the diagnostic should not imply that the argument is a list when it isn't.
* New accessor: mref.Kaz Kylheku2023-11-151-0/+12
| | | | | | | | | | | | | | * eval.c (eval_init): Register mref intrinsic. * lib.[ch] (mref): New function. * stdlib/place.tl (sys:mref1): New place. (mref): New place macro, defined in terms of sys:merf1, ref place and mref function. * tests/012/seq.tl: New tests. * txr.1: Documented.
* New: length-list-<, length-<Kaz Kylheku2023-10-051-0/+28
| | | | | | | | | | | | | | | | | | | | | | These are functions for testing whether a list or sequence is shorter than a given integer. This is cheaper than calculating the length of lists, which is in some cases impossible if they are infinite. A length-str-< function already exists, useful with lazy strings. length-< uses length-list-< or length-str-< as appropriate * lib.[ch] (length_list_lt, length_lt): New functions. * eval.c (eval_init): length-list-< and length-< intrinsics registered. * tests/012/seq.tl: New tests. * txr.1: Documented.
* flatten*: fix two bugs.Kaz Kylheku2023-09-301-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (lazy_flatten_scan): Fix a problem which results in cases like (()), ((())) ... to incorrectly flatten to (nil). The do loop in this function which iteratively descends into a nested left-nesting of a list does not handle all cases, and therefore the function may not return at that point. Removing the return fixes the problem, but so does removing the loop so that in that case we just descend one level into the nested list, and continue in the main loop. What is incorrect is that when the consp(a) test fails and the do loop terminates, we need to distinguish the cases off a being an atom versus nil. Continuing in the loop does that. This bug was spotted by a reviewer in the comp.lang.c Usenet newsgroup. (lazy_flatten): We neglect to handle the case here that the input is an empty list, resulting in (flatten* nil) returning (nil) rather than nil. The flatten function is correct. * tests/012/seq.tl: New tests. * txr.1: Documentation improved. In particular, these functions don't handle improper lists. Also, it needs to be documented that the argument may be an atom.
* New hist-sort function.Kaz Kylheku2023-09-251-3/+22
| | | | | | | | | | | | | | | * eval.c (eval_init): Register hist-sort intrinsic. * lib.c (gt_f): New global variable. (hist_succ_f): New static variable. (hist_succ): New static function. (hist_sort): New function. * lib.h (gt_f, hist_sort): Declared. * tests/012/sort.tl: New tests. * txr.1: Documented.
* New functions: nested-vec-of and nested-vec.Kaz Kylheku2023-09-211-20/+69
| | | | | | | | | | | | | | | * eval.c (eval_init): Register nestd-vec-of and nested-vec intrinsics. * lib.[ch] (vec_allocate, vec_own, vec_init): New static functions. (vector, copy_vec): Expressed in terms of new functions. (nested_vec_of_v, nested_vec_v): New functions. * args.[ch] (args_cat_from): New function. * tests/010/vec.tl: New tests. * txr.1: Documented.
* Use vargs typedef instead of struct args *.Kaz Kylheku2023-09-051-38/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | The vargs typedef is underused. Let's use it consistently everywhere. * args.c, * args.h, * args.c, * args.h, * arith.c, * eval.c * ffi.c, * gc.c, * hash.c, * lib.c, * lib.h, * parser.c, * stream.c, * struct.c, * struct.h, * syslog.c, * syslog.h, * unwind.c, * vm.c, * vm.h: All "struct args * declarations replaced with existing "varg" typedef that comes from lib.h.
* json: allow integers and lists.Kaz Kylheku2023-09-031-7/+15
| | | | | | | | | | | | * lib.c (out_json_rec): Handle NUM and BGNUM cases same as FLNUM so integers get printed. The restriction against integers has been largely unhelpful and bothersome. Handle LCONS together with CONS. Lists that are not special notation fall through to the VEC case, which now uses seq_iter_t iteration to handle vectors and lists. * tests/010/json.tl: New tests. * txr.1: Documented support for printing integers and lists.
* New function: str-esc.Kaz Kylheku2023-09-011-0/+20
| | | | | | | | | | * lib.[ch] (str_esc): New function. * eval.c (eval_init): str-esc intrinsic registered. * tests/015/esc.tl: New file. * txr.1: Documented.
* unuse-sym: fix in face of use-sym-as.Kaz Kylheku2023-08-101-0/+10
| | | | | | | | | | | | | * lib.c (unuse_sym): A used symbol may now appear in a package under a different name. So if we don't find a symbol under the symbol's name, or find a different symbol, we must try a reverse hash search before giving up. * txr.1: Add notes to use-sym-as that unuse-sym must be used to undo its effect. Add notes to unuse-sym discussing similarities and differences versus unintern. * tests/012/use-as.tl: New test cases.
* New feature: local symbol renaming.Kaz Kylheku2023-08-101-3/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The new function use-sym-as can bring a foreign symbol into a package under a different name, which is not that symbol's name. This is also featured in a new defpackage clause, :use-syms-as. With this simple relaxation in the package system, we don't require package local nicknames, which is more complicated to implement and less ergonomic, because it doesn't actually vanquish the use of ugly package prefixes on clashing symbols. * eval.c (eval_init): Register use-syms-as. * lib.c (use_sym_as): New function, made out of use_sym. (use_sym): Now a wrapper for use_sym_as. * lib.h (use_sym_as): Declared. * stdlib/package.tl (defpackage): Implement :use-syms-as clause. * tests/012/use-as.tl: New file. * txr.1: Documented, * stdlib/doc-syms.tl: Updated.
* del/replace with index-list: fix semantics.Kaz Kylheku2023-07-181-11/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit does two things. The replace function, implemented under the hood by four specializations: replace-list, replace-vec, replace-str and replace-buf, will handle the index-list case a little differently. This is needed to fix the ability of the del macro work on place designated by an index list, such as: (del [sequence '(1 3 5 6)] which now deletes elements 1, 3, 5 and 6 from the sequence, and returns a sequence of those items. The underlying implementation uses replace with an index-list, which is now capable of deleting items. Previously, replace would stop processing the index list when the replacement-sequence corresponding to the index list ran out of items. Now, when the replacement-sequence runs out of items, the remaining index-list sequence elements specify items to be deleted. For instance if str holds "abcdefg" then: (set [str '(1 3 5)] "xy") will change str to "axcyeg". Elements 1 and 3 are replaced by x and y, respectively. Element 5, the letter f, is deleted, because the replacement "xy" has no element corresponding to 5. * lib.c (replace_list, replace_str, replace_vec): Implement new deleteion semantics for the case when the replacement sequence runs out of items. * buf.c (replace_buf): Likewise. * tests/010/seq.txr: Some new test cases here for deletion. * tests/010/seq.expected: Updated. * txr.1: Documented new semantics of replace, including a new restriction that if elements are being deleted, the indices should be monotonically increasing regardless of the type of the sequence (not only list). A value of 289 for the -C option documented, which restores the previous behavior of replace (breaking deletion by index-list, unfortunately: you don't always get to simulate an old version of TXR while using new features.)
* printer: print (sys:vector-list ()) as #() not #nil.Kaz Kylheku2023-07-171-1/+4
| | | | | * lib.c (obj_print_impl): Check for this case and handle. The #nil syntax is not readable.
* unique: use sequence iterationKaz Kylheku2023-07-101-20/+8
| | | | | * lib.c (unique): Use seq_iter_t rather than dividing into list and vector cases.
* Bug: ranges not treated as iterable in some situations.Kaz Kylheku2023-06-301-1/+1
| | | | | | | | | | | | | * lib.c (seq_kind_tab): Map the RNG type to SEQ_VECLIKE rather than SEQ_NOTSEQ. This one liner change causes ranges to be rejected for iteration needlessly. For instance, we can now do (take 42 "00".."99"). Note that ranges are not literally vector-like; they don't support the ref operation. The effect of this change is simply that they are not rejected due to being SEQ_NOTSEQ. The iteration code already handles RNG specially, so the SEQ_VECLIKE classification doesn't actually matter.