summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
* lib: new function vm-fun-p.Kaz Kylheku2018-04-071-0/+5
| | | | | | | | * eval.c (eval_init): vm-fun-p intrinsic registered. * lib.c (vm_fun_p): New function. * lib.h (vm_fun_p): Declared.
* vm: allow vm description to be callable as function.Kaz Kylheku2018-04-061-0/+4
| | | | | | | * lib.c (generic_funall): Handle vm-desc objects via vm_execute_toplevel. * vm.h (vm_desc_s, vm_closure_s): Declared.
* Application code is now in a package called pub.Kaz Kylheku2018-04-091-2/+4
| | | | | | | | | | | | | | | * lib.c (public_package): New variable. (obj_init): Protect public_package from gc. Initialize it with a package called "pub" which has the user package in its fallback list. * lib.h (public_package): Declared. * eval.c (eval_init): Initialize package_s to public_package rather than user_package, except in compat <= 190 mode. * txr.c (txr_main): Bind *package* to public_package rather than user_package, except in compat <= 190 mode.
* lib: get rid of preprocessor macros for packages.Kaz Kylheku2018-04-051-5/+5
| | | | | | | | | | | | | | | | | | | | | | | The identifiers user_package, system_package and keyword_package are preprocessor symbols that expand to other preprocessor symbols for no good reason. Time to get rid of this. * lib.c (system_package_var, keyword_package_var, user_package_var): Variables renamed to system_package, keyword_package and user_package. (symbol_package, keywordp, obj_init): Fix variable references to follow rename. * lib.h (keyword_package, user_package, system_package): Macros removed. (system_package_var, keyword_package_var, user_package_var): Variables renamed. * eval.c (eval_init): Fix variable references to follow rename. * parser.y (sym_helper): Likewise.
* printer: improve object formatting.Kaz Kylheku2018-04-051-2/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is an issue with the printer in that it produces output whereby objects continue on the same line after a multi-line object, e.g: (foo (foobly bar xyzzy quux) (oops same line)) rather than: (foo (foobly bar xyzzy quux) (oops same line)) There is a simple fix for this: set a flag to force a line break on the next width-check operation whenever an object has been broken into multiple lines. width-check can return a Boolean indication whether it generated a line break, and so aggregate object printing routines can tell whether their object has been broken into lines, and set the flag. * stream.h (struct strm_base): New member, force_break. (force_break): Declared. * stream.c (strm_base_init): Extent initializer to cover force_break flag. (put_string, put_char): Clear the force_break flag whenever we hit column zero. (width_check): If indent mode is on, and force_break is true, generate a break. Clear force_break. (force_break): New function. (stream_init): Register force-break intrinsic. * buf.c (buf_print): Set the force break flag if the buffer was broken into multiple lines. * hash.c (hash_print_op): Set the force break flag if the hash was broken into multiple lines. * lib.c (obj_print_impl): Same logic for lists. * struct.c (struct_inst_print): Same logic for structs. * tests/009/json.expected, tests/011/macros-2.expected, tests/012/struct.tl, tests/017/glob-zarray.expected: Update expected textual output to reflect new formatting.
* regex: read/print bug: escaped double quote.Kaz Kylheku2018-04-041-3/+8
| | | | | | | | | | | | | | | | | | | Because the regex printer wrongly uses out_str_char (for the sake of borrowing its semicolon-notation processing) when a regex prints, all characters that require escaping in a string literal get escaped, which includes the " character. Unfortunately the \" sequence which results is rejected by the regex parser. * lib.c (out_str_char): Kludge: add extra argument to distinguish regex use versus string use, and treat the double quote accordingly. (out_str_readable): Give 0 arg to new param of out_str_char. * lib.h (out_str_char): Declaration updated. * regex.c (print_class_char, print_rec): Pass 1 to new param of out_str_char.
* packages: fix package prefix read/print issue.Kaz Kylheku2018-04-031-2/+44
| | | | | | | | | | | | | | | | | | | | | | | | Suppose that we have two symbols of the same name, in two packages: foo:sym and bar:sym. Suppose that the bar package has foo in its package fallback list, and suppose bar is the current package. Then bar:sym prints without a package prefix, as just sym. However, this is potentially ambiguous. Suppose that bar:sym is written to a file as just sym. Then later the file is read into a fresh image in a situation in which bar:sym has not yet been interned, but foo:sym already exists. In this situation, sym will just resolve to foo:sym. The printer must detect this ambiguous situation. If a symbol is present in a package, but a same-named symbol is in the fallback list; or if a symbol is visible in the fallback list, but a same-named symbol is present in the package, then a package prefix should be printed. * lib.c (symbol_needs_prefix): New function. (unquote_star_check, obj_print_impl): Use symbol_needs_prefix rather than symbol_visible. * lib.h (symbol_needs_prefix): Declared.
* lib: elminate reduce_right from expt.Kaz Kylheku2018-03-291-1/+9
| | | | | | * lib.c (rexpt): New static function. (exptv): Create reversed arguments on the stack, then process with nary_op and the rexpt shim.
* lib: eliminate reduce-left from n-ary math ops.Kaz Kylheku2018-03-291-36/+44
| | | | | | | | | | | | | | | | Using reduce-left is inefficient; it conses up a list. We can decimate the stacked arguments without consing. * lib.c (nary_op): Replace reduce_left with iteration. (nary_simple_op): New function, variant of nary_op useable by functions that have a mandatory argument passed separately from the argument list. (minusv, divv): Replace reduce_left with iteration. (maxv, minv): Replace reduce_left with nary_simple_op. (abso_self): New static function. (gcdv, lcmv): Replace reduce_left with nary_op. * lib.h (nary_simple_op): Declared.
* vm: funcall wrappers need to check arg count.Kaz Kylheku2018-03-201-0/+16
| | | | | | | | | | | | | | There is the possibility that funcall1 through funcall3 will pass the wrong number of arguments to vm_execute_closure, which doesn't do any checks. This is only for the code paths which don't go through generic_funcall, when the function has no optional arguments. * lib.c (funcall1, funcall2, funcall3, funcall4): Check that the closure doesn't require more fixed parameters than we're giving it in the variadic case, or that it doesn't require a different number of fixed parameters we're giving it in the non-variadic case.
* lib: new ldiff function.Kaz Kylheku2018-03-201-1/+56
| | | | | | | | | | * eval.c (eval_init): Use the old ldiff function under compatibility with 190 or lower. * lib.c (ldiff): Rewritten. (ldiff_old): New function, copy of previous version of ldiff. * lib.h (ldiff_old): Declared.
* vm: variadic arg closures bug 1/3.Kaz Kylheku2018-03-191-1/+1
| | | | | | | * lib.c (func_vm): fix incorrect assignment of int boolean to one-bit-wide bitfield. The argument isn't zero or one; in fact the value 256 gets passed down representing true. This gets truncated to one bit which is zero.
* vm: handle FVM function type thorughout run-time.Kaz Kylheku2018-03-161-1/+46
| | | | | | | | | | | | | | | | * gc.c (mark_obj): Recognize FVM functions and mark their vm_desc. * lib.c (equal): Handle equality for FVM. If the environment pointers are equal, consider the functions equal. (funcall, funcall1, funcall2, funcall3, funcall4): Recognize and call FVM functions. However, there is a lack of robustness here that needs to be addressed: vm_execute_closure doesn't check whether there are too many or not enough arguments. Interpreted functions have a run-time check inside bind_args. (obj_print_impl): Don't print VM functions as #<intrinsic fun...> but rather #<vm fun>.
* vm: bugfix: wrong setup of closure param counts.Kaz Kylheku2018-03-151-1/+1
| | | | | | * lib.c (func_vm): The fixparam argument is the total number of fixed parameters, including optionals. That argument must be stored in the same-named member of the function structure.
* regression: excess args not diagnosed.Kaz Kylheku2018-03-131-1/+1
| | | | | | | | | | | This was caused by the recent work to reduce consing in generic_funcall. * lib.c (generic_funcall): Correct test for too many arguments. Because we don't normalize the argument list to the exact number of fixed args, but to at least the fixed args, the excess args can possibly be part of the fill rather than part of the list.
* New: virtual machine with assembler.Kaz Kylheku2018-03-101-33/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit is the start of compiler work to make TXR Lisp execute faster. In six days of part time work, we now have a register-style virtual machine with 32 instructions, handling exceptions, unwind-protect, lexical closures, and global environment access/mutation. We have a complete assembler and disassembler for this machine. The assembler supports labels with forward referencing with backpatching, and features pseudo-ops: for instance the (mov ...) pseudo-instruction chooses one of three kinds of specific move instruction based on the operands. * Makelfile (OBJS): Add vm.o. * eval.c (lookup_sym_lisp1): Static function becomes external; the virtual machine needs to use this to support that style of lookup. * genvmop.txr: New file. This is the generator for the "vmop.h" header. * lib.c (func_vm): New function. (generic_funcall): Handle the FVM function type via new vm_execute_closure function. In the variadic case, we want to avoid the argument copying which we do for the sake of C functions that get their fixed arguments directly, and then just the trailing arguments. Thus the code is restructured a bit in order to switch twice on the function type. (init): Call vm_init. * lib.h (functype_t): New enum member FVM. (struct func): New member in the .f union: vm_desc. (func_vm): Declared. * lisplib.c (set_dlt_entries_impl): New static function, formed from set_dlt_entries. (set_dlt_entries): Reduced to wrapper for set_dlt_entries_impl, passing in the user package. (set_dlt_entries_sys): New static function: like set_dlt_entries but targetting the sys package. (asm_instantiate, asm_set_entries): New static functions. (lisplib_init): Auto-load the sys:assembler class. * share/txr/stdlib/asm.tl: New file. * vm.c, vm.h, vmop.h: New files.
* sys package fall back on usr.Kaz Kylheku2018-03-091-0/+2
| | | | | | | | | * lib.c (obj_init): Give the system package a fallback list consisting of one element: the user package. This will make it easier to develop some library features that have lots of internal symbols that ought to be hidden in the system package, without having to put sys: on everything. That code will just switch to the system package.
* args: overhaul for clarity and reduced consing.Kaz Kylheku2018-03-091-19/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * args.c (args_normalize): Renamed to args_normalize_exact, because this tries to split the arguments between an exact array fill quantity and trailing list. Not all places using this function actually need an exact fill, which causes unnecessary consing when args->fill is reduced in order to move items to args->list. (args_normalize_least): New function. Variant of args_normalize that can be used by functions which only require a minimum fill. (args_normalize_fill): Use args_normalize_least rather than args_normalize_exact. This reduces consing in generic_funcall, in handling variadic calls where arrayed arguments have been supplied for trailing parameters. * args.h (args_normalize): Renamed to args_normalize_exact. (args_normalize_least): Declared. (args_get_list, args_get_rest): Use args_normalize_exact. (args_clear): Inline function removed. Was used only in one place in generic_funcall and is no longer. * eval.c (gather_free_refs): Use args_normalize_least. (prod_common): Use args_normalize_exact. * ffi.c (ffi_call_wrap): Use args_normalize_least. * lib.c (generic_funcall): Use args_normalize_least in switch statement that handles various callable non-function objects. When copying args, ensure that there are ARGS_MIN. A different strategy is used for producing the trailing args for variadic calls, further reducing consing. Rather than normalize the args to the fixed number, and then set args->fill to zero so that args contains just the list, we use args_cat_zap_from to create a copy of the args in which the fixed ones are trimmed out. The resulting args is not renormalized to be purely a list so no consing or list traversal takes place. If the rebalancing is needed, the called function will have to do it. (dwim_set): Streamline the code that handles hashes assigned via two or three args. * struct.c (method_args_fun, umethod_args_fun): Use args_normalize_exact.
* code review: switch case breaks.Kaz Kylheku2018-03-081-0/+1
| | | | | | | | | | * arith.c (c_unum): Add fallthrough comment. (minus): Add missing break after case that handles char minus heap object.. This luckily isn't a bug because type(anum) isn't RNG, and so when it falls through, the next case also falls through. * lib.c (car): Add missing fallthrough comment.
* Copyright year bump 2018.Kaz Kylheku2018-02-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, Makefile, args.c, args.h, arith.c, arith.h, buf.c, buf.h, cadr.c, cadr.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, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/error.tl, share/txr/stdlib/except.tl, share/txr/stdlib/ffi.tl, share/txr/stdlib/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/keyparams.tl, share/txr/stdlib/op.tl, share/txr/stdlib/package.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/stream-wrap.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/tagbody.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, strudel.c, strudel.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, win/cleansvg.txr: Extended Copyright line to 2018.
* tail: reduce calls to cdr.Kaz Kylheku2018-01-071-2/+3
| | | | | | * lib.c (tail): Don't call cdr on the same cell twice in the loop body. tail is used in list_collect and friends, which are used all over the place.
* term: move near site of use.Kaz Kylheku2018-01-071-7/+0
| | | | | | | | | * eval.c (term): Function here from lib.c, and changed to static. It is used only by iapply. * lib.c (term): Function moved to eval.c. * lib.h (term): Declaration removed.
* listref_l: remove.Kaz Kylheku2018-01-061-17/+0
| | | | | | * lib.c (listref_l): Unused function removed. * lib.h (listref_l): Declaration removed.
* refset: implement objects that support car method.Kaz Kylheku2018-01-061-12/+46
| | | | | | | | | | | | | | refset and range assignment is implemented for objects that have no lambda-set but do have a car method. * lib.c (refset): Implementation for lists rewritten to avoid listref_l, and use nthcdr instead. For structs, if there is no lambda-set method, but a car method exists, jump to the list case: the idea is that we can cdr down and then use rplaca. (dwim_set): Error handling streamlined. In this function too, we check whether there is a car method and branch to the list case.
* nthcdr: terminate loop if end of list hit.Kaz Kylheku2018-01-051-1/+1
| | | | | * lib.c (nthcdr): Terminate loop when nil is hit rather than continuing to count down to zero.
* car, cdr: self-identify in error message.Kaz Kylheku2018-01-051-2/+2
| | | | | * lib.c (car, cdr): Type mismatch messages now identify functions.
* car, cdr: fall back on lambda method.Kaz Kylheku2018-01-031-4/+24
| | | | | | * lib.c (car, cdr): Don't fail if the struct object has no car or cdr method. Use it if it is available, otherwise try to fall back on the lambda method if that is available.
* ltail: unused function.Kaz Kylheku2018-01-021-7/+0
| | | | | | | | * lib.c (ltail): Function removed. This was introduced at the same time as lazy_appendv and used only by it. That function was rewritten a few months ago and doesn't use lail. * lib.h (ltail): Declaration removed.
* seq_info: bugfix: wrong object tested obj_struct_p.Kaz Kylheku2018-01-021-1/+1
| | | | | | * lib.c (seq_info): The obj_struct_p test must be applied to obj, not to cls, which is a symbol. Due to this bug, seq_info would always report struct-based sequences as SEQ_NOTSEQ.
* seq_info: whitespace.Kaz Kylheku2018-01-021-1/+1
| | | | | * lib.c (seq_info): Incorrect indentation of else statement fixed.
* last: rewrite using seq_info.Kaz Kylheku2018-01-021-10/+17
| | | | | * lib.c (last): Use seq_info classification rather than relying on listp.
* eliminate cdr_l use from implementation of last.Kaz Kylheku2018-01-021-11/+7
| | | | | | * lib.c (lastcons): Return value is just the last cons rather than a loc. The only caller of this function is last. (last): Adapt to the new lastcons.
* Use rplaca and rplacd instead of set over car_l/cdr_l.Kaz Kylheku2018-01-011-6/+6
| | | | | | | | | | | | | | | | | | | | | | | This reduces the proliferation of car_l and cdr_l. With this change, nreverse should work on chains of objects that implement rplacd. * combi.c (comb_gen_fun_common, rcomb_gen_fun_common): Use rplaca. * eval.c (mappendv, mapdov): Likewise * hash.c (hash_equal_op): Likewise. * lib.c (nreverse, acons_new, aconsql_new, sort_list): Use rplaca and rplacd. * match.c (dest_set, v_gather, v_collect, v_flatten, v_cat, v_output, v_filter): Likewise * parser.c (ensure_parser): Use sys_rplacd. * unwind.c (uw_register_subtype): Use rplacd.
* sub and replace redirect to structure methods.Kaz Kylheku2018-01-011-5/+36
| | | | | | | | | | | | | * lib.c (replace_obj): New static function. (sub): Handle struct case via lambda method. (replace): Handle struct case via replace_obj. * txr.1: Documented. * tests/012/aseq.tl (add): The lambda method now has to handle a range argument. One test case uses the last function, which for non-lists relies on sub, which now calls the lambda method if the object has one.
* New inlined test for struct object.Kaz Kylheku2017-12-311-14/+14
| | | | | | | | | | | * lib.c (seq_info, car, cdr, make_like, nullify, generic_funcall, copy, length, empty, ref, refset, dwim_set, dwim_del, populate_obj_hash): Use new obj_struct_p test when we know that the object is a COBJ. * struct.c (struct_inst_ops): Change from static to extern. * struct.h (ob_struct_p): New inline function.
* New methods rplaca and rplacd.Kaz Kylheku2017-12-301-0/+32
| | | | | | | | | | | | | | | * eval.c (eval_init): Register rplaca and rplacd using new rplaca_s and rplacd_s symbol variables. * lib.c (rplaca_s, rplacd_s): New symbol variables. (rplaca): Handle struct object via rplaca method, if it has one, otherwise lambda-set, if it has that, or else error out. (rplacd): Handle struct object via rplacd method. * lib.h (rplaca_s, rplacd_s): Declared. * txr.1: Documented rplaca and rplacd methods.
* refset: better diagnostics.Kaz Kylheku2017-12-291-1/+3
| | | | | | * lib.c (refset): If structure has no lambda-set method, diagnose it like that, rather than "not a sequence". Also, diagnostics should use refset:, not ref:.
* New feature: structure delegate streams.Kaz Kylheku2017-12-081-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A new kind of stream object which redirects its operations to the methods of a structure. * Makefile (OBJS): New object file, strudel.o. * lib.c (init): Call new strudel_init function. * lisplib.c (stream_wrap_set_entries, stream_wrap_instantiate): New static functions. (lisplib_init): Arrange for autloading of new stream-wrap.tl. * share/txr/stdlib/stream-wrap.tl: New file. * stream.c (put_string_s, put_char_s, put_byte_s, get_line_s, get_char_s, get_byte_s, unget_char_s, unget_byte_s, put_buf_s, fill_buf_s, flush_s, seek_s, truncate_s, get_prop_s, set_prop_s, get_error_s, get_error_str_s, clear_error_s, get_fd_s): New symbol variables. (stream_init): New symbol variables initialized. Numerous functions registered via these variables now rather than intern(...) expressions. * stream.h (put_string_s, put_char_s, put_byte_s, get_line_s, get_char_s, get_byte_s, unget_char_s, unget_byte_s, put_buf_s, fill_buf_s, flush_s, seek_s, truncate_s, get_prop_s, set_prop_s, get_error_s, get_error_str_s, clear_error_s, get_fd_s): Declared. * strudel.c, strudel.h: New files.
* Rewrite internal mapping function.Kaz Kylheku2017-11-301-4/+21
| | | | | | * lib.c (mapcar_listout): Rework using seq_info for efficient processing of vector-like sequences and objects that implement sequences.
* Fix quoted function name in unsupported object errors.Kaz Kylheku2017-11-231-11/+17
| | | | | | | | | * lib.c (unsup_obj): New static function. (grade, find, rfind, find_max, find_if, rfind_if, pos, rpos, pos_if, rpos_if, pos_max): Replace call to uw_throwf with call to unsup_obj. IN all these functions except grade, the ~s conversion specifier was wrongly used on the function name rather than ~a, resulting in unwanted quoting.
* New function: grade.Kaz Kylheku2017-11-231-0/+43
| | | | | | | | | | | | Inspired by APL. * eval.c (eval_init): Register grade intrinsic. * lib.c (grade): New function. * lib.h (grade): Declared. * txr.1: Documented.
* lastcons: streamline.Kaz Kylheku2017-11-221-1/+1
| | | | | * lib.c (lastcons): Don't wastefully call cdr on an object after called cdr_l; just dereference the cdr_l loc.
* bugfix: tail handles improper list.Kaz Kylheku2017-11-221-1/+1
| | | | | | | | | | | * lib.c (tail): This low-level function is used by the list accumulation routines. Because it doesn't handle improper lists, looking for a null terminator, certain things don't work, like the associativity of append. For instance (append '(1 2) #(3) 4) works but not (append (append '(1 2) #(3)) 4). Fixing tail so that it terminates on any atom, rather than failing trying to cdr through it.
* bugfix: two issues in mappend* and append*.Kaz Kylheku2017-11-211-29/+23
| | | | | | | | | | | | | | | | | | | | | | | Two bugs in these functions, both attributable to the lazy_appendv implementation: They destructively catenate the input lists, much like nconc, even though documented as non-destructive. If any input list is infinite, other than the last input list, that list is forced, resulting in an infinite loop. * lib.c (lazy_appendv_func): Rewritten to use a different algorithm which earnestly allocates a new lazy cons for each element of the output sequence, except for the tail part corresponding to the last list. (lazy_appendv): Set up the lazy cons according to the new representation and just return it. No searching for the tail of the nonempty list, and no destructive manipulation.
* Use fixnum indices for vector iteration.Kaz Kylheku2017-11-161-41/+51
| | | | | | | | | | | * lib.c (find, rfind, find_max, find_if, rfind_if, pos, rpos, pos_if, rpos_if, pos_max): Consistently fixnum indices for iterating over vector. In some functions, a cnum is already used, but could be out of fixnum range; we switch to using c_fixnum for extracting the length and then num_fast on the index. Some functions are converted from using a val index. In the case of rfind_if, a bug is fixed: it was using plusp, which now becomes the correct >= 0.
* pos-max: rewrite.Kaz Kylheku2017-11-161-18/+48
| | | | * lib.c (pos_max): Rewrite using seq_info.
* find-max: bugfix for zero length vectors.Kaz Kylheku2017-11-151-10/+15
| | | | | | * lib.c (find_max): Fix a regression introduced in recent work: only execute the loop when the vector isn't empty.
* pos-if, rpos-if: rewrite.Kaz Kylheku2017-11-151-25/+72
| | | | * lib.c (pos_if, rpos_if): Rewrite using seq_info.
* posq, posql, posqual, rposq, rposql, rposqual: rewriteKaz Kylheku2017-11-151-93/+30
| | | | | | | * lib.c (posq, posql, posqual, rposq, rposql, rposqual): These functions are reduced to wrappers around pos and rpos, respectively, so they generalize properly and efficiently to sequences of all kinds.
* pos, rpos: rewrite with seq_info.Kaz Kylheku2017-11-151-57/+88
| | | | | | | * lib.c (pos, rpos): Functions rewritten to use the seq_info sequence classification mechanism. The rpos function is thereby optimized to work with vectors. Both functions support vector-like struct objects now.