summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
...
* lib: new functions join, join-with.Kaz Kylheku2021-03-091-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | That old cat-str function is often a pain, requiring the pieces as a list. We have a sys:fmt-join that is undocumented. That functions is now exposed as usr:join, and documented. Also introducing join-with that takes a separator as the leftmost argument. Thus (op join-with "::") gives us a function that joins pieces with :: in between. * eval.c (eval_init): Regiser fmt_join function under join symbol also. Register join-with. * lib.c (join_with): New function. (fmt_join): Now a wrapper for join_with that passes a nil separator. * lib.h (join_with): Declared. * share/txr/stdlib/optimize.tl (basic-blocks join-blocks): Rename the local function join, which now triggers a warning about a standard function being redefined. * txr.1: Redocumented cat-str, and documented join-with and join.
* lib: defend against locale-specific wcstod.Kaz Kylheku2021-03-041-2/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The wcstod function has locale-specific behavior. It uses a locale-specific decimal separator character, which may not be the period. Though in TXR we never call setlocale in order to activate localization, it is a good idea to put in code to defend against this. If locale is ever unleashed on the code, it really botches our floating-point handling. However, let's keep that defensive logic disabled for now using the preprocessor. The strategy is to inquire about the locale's decimal character at startup. Then, in the flo_str function, we preprocess the input by converting the decimal period to the locale-specific character before calling wcstod. On the output side, we also deal with it in the format function; we call sprintf, and then convert the locale-specific characer to period. I tested all this by temporarily introducing the setlocale call, and switching to a locale with a comma as the separator, geting make tests to pass, and doing some interactive testing. This is not going to receive coverage in the test suite. * lib.c (dec_point): New global variable. (flo_str): If dec_point isn't '.', we must copy the string into a local buffer, which we get from alloca, and edit any '.' that it contains to dec_point. (locale_init): New function; initializes dec_point. (init): Call locale_init. * lib.h (dec_point): Declared. * stream.c (formatv): Don't look for a '.' in the result of printing a double using %e; look for dec_point. Post-process floating-point sprinf by substituting occurrences of dec_point with the period.
* printer: lambda bugfix.Kaz Kylheku2021-02-121-1/+1
| | | | | | | | | | | * lib.c (obj_print_impl): Don't pass non-symbols to fboundp. This causes a problem in the case where we are printing an object like ((lambda ...) ...). The car of this object is the (lambda ...) form. When when pass this to fboundp, the underlying function lookup mechanism wants to turn it into a function object and tries to expand it. This can error out if the lambda has bad syntax, which can happen because it's just data that we are trying to print.
* multi-sort: bug: always return list of lists.Kaz Kylheku2021-02-071-6/+13
| | | | | | | * lib.c (multi_sort): If any of the input lists is empty, then there is an empty list of tuples to sort, producing a an empty list that doesn't transpose back to a list of empty lists. We code this as a special case.
* lib: code review of get_special_slot uses.Kaz Kylheku2021-02-021-24/+23
| | | | | | | | | | | | | * lib.c (seq_info): Streamline code. Initialize ret.kind to SEQ_NOTSEQ to avoid repeating that in multiple else clauses. Make sure that if the nullify method returns nil, we also return in that case, and don't call get_special_slot on nil. (rplaca, rplacd): Change the default case to COBJ, so that the obj_struct_p inline can be used instead of structp. Put the default: label on the error case which the struct check falls through to; NIL now goes there. (sub): Use obj_struct_p, not structp, in a case where we already know we have a COBJ.
* lib: fix crash in iterable and nullify.Kaz Kylheku2021-02-021-1/+1
| | | | | | | * lib.c (seq_iterable): In the COBJ case, we must check whether the object is a structure before accessing get_special_slot. For instance (nullify #/a/) crashes because a regex is a COBJ but not a struct.
* lib: get rid of alist_remove1 function.Kaz Kylheku2021-01-311-6/+1
| | | | | | | * lib.c (delete_package): This is the only user of alist_remove1. It can use remqual with a car_f key, which is more efficient. (alist_remove1): Function removed.
* lazy-sub-str: bugfix: invalid substructure sharing.Kaz Kylheku2021-01-251-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | This addresses a bug manifesting itself as a regression in the behavior of @(freeform), which was reported by Frank Schwidom. The sub_str operation calls lazy_subs_str for a lazy string. But lazy_sub_str again relies on sub_str for extracting part of the lazy string prefix. But sub_str can potentially return the whole object rather than a copy of a substring of it. In this case, lazy_sub_str produces a new lazy string object which shares the prefix string object with the original lazy string. This is incorrect because the lazy string data type destructively manipulates the prefix. It means that operations one one lazy string are mucking with the prefix of another lazy string. * lib.c (lazy_sub_str): When creating the new lazy string object, make a copy of the prefix string pulled from the original. We do the carefully: the copy of the prefix is made before the make_obj call which allocates the new lazy string, otherwise we create a wrong-way assignment from the perspective of generational GC. * tests/006/freeform-4.txr: New test case, from Frank. * tests/006/freeform-4.expected: Expected output of test case.
* sub-str: compat check now restores 215 behavior.Kaz Kylheku2021-01-251-1/+3
| | | | | | | | | | | * lib.c (sub_str): If compatibility is requested, with a value of 215 or less, then disable the optimization of returning the original string without making a copy. This was found to break the @(freeform) directive. That regression alerts me to the fact that I should have made this subject to compatibility; some user code could be affected. * txr.1: New compat note added, under 215.
* printer: do not render @(rcons ...) in .. notation.Kaz Kylheku2021-01-241-2/+11
| | | | | | | | | | | | | | | | | | | | | | | This fixes the following print-read consistency issue. Both of these objects print as @a..@b. 1> '@(rcons a b) @a..b 2> '(rcons @a b) @a..b We want only the second case. After the this fix: 1> '(rcons @a b) @a..b 2> '@(rcons a b) @(rcons a b) * lib.c (obj_print_impl): In the sys:expr case, we check whether the head of the argument is rcons. If so, we adjust a few local variables and branch directly to the generic list case via goto to print the argument as (rcons ...) without conversion to dotdot range notation.
* printer: do some streamlining.Kaz Kylheku2021-01-241-26/+27
| | | | | | * lib.c (obj_print_impl): Capture some values into local variables to avoid repeating the type-checked accesses. Many of the cases access the first argument, and such.
* bugfix: several predicates return 1 instead of t.Kaz Kylheku2021-01-211-13/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Firstly, I'm fixing an odd bug here: cobjclassp returns 1 instead of t to represent true. This affects: carrayp, hashp, random-state-p, regexp and struct-type-p, all of which return 1 when the test is true. For some bizarre reason, I chose this weird solution back in 2019 because this function has some calls at init time when t is not yet available; simply returning t causes a segfault. Secondly, I'm fixing the way we deal with t at initialization time. We simply give it a temporary value of 1 until it is replaced with the real symbol. This fixes all the original problems with t being nil until initialized. Now, we cannot do this: val t = one; because one is not a constant expression due to the cast, even though one is a de-facto constant. That's probably what distraced me away from the obvious second-best solution of just assigning it at some early point in the execution. * lib.c (cobjclassp): Fix odd bug here: returning one to indicate true instead of t. (make_sym): Don't test value of t here any more. (make_package_common): Don't use lit("t") instead of t any more in the make_hash calls. (make_package): Don't test value of t here. (obj_init): t can now be initialized using the straightforward expression t = intern(lit("t"), user_package), similarly to other symbols. (init): set t to the integer 1 before making any init calls.
* iter-step: don't step through improper list terminators.Kaz Kylheku2021-01-211-1/+20
| | | | | | | | | | | | | | | | The issue is that iter-step will traverse (1 2 . 3) into the 3, and then that is valid iterator which continues via 4, 5, 6, ... This affects the each operator family which use iter-step. * lib.c (iter_step): Handle CONS and LCONS specially now. If the next object pulled via cdr is not a cons, and not nil, then throw an error. The default case now only possibly handles list-like sequences. Here we do something more generic and expensive: we enforce that the next iterator must be nil, or else a list-like sequence.
* Copyright year bump 2021.Kaz Kylheku2021-01-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * METALICENSE: 2020 copyrights bumped to 2021. Added note about SHA-256 routines from Colin Percival. * LICENSE, LICENSE-CYG, Makefile, alloca.h, args.c, args.h, arith.c, arith.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, hash.c, hash.h, itypes.c, itypes.h, jmp.S, lex.yy.c.shipped, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.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/asm.tl, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/compiler.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/copy-file.tl, share/txr/stdlib/debugger.tl, share/txr/stdlib/defset.tl, share/txr/stdlib/doloop.tl, share/txr/stdlib/each-prod.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/param.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/pmac.tl, share/txr/stdlib/quips.tl, share/txr/stdlib/save-exe.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/trace.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/vm-param.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, 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 2021.
* shuffle/nshuffle: take optional random state argument.Kaz Kylheku2020-12-291-4/+4
| | | | | | | | | | | | | * eval.c (eval_init): Register shuffle and nshuffle as two-argument functions with optional argument. * lib.c (nshuffle): Take random-state argument, defaulting to value of random_state special variable. (shuffle): Take random-state argument, pass down to nshuffle. * lib.h (shuffle, nshuffle): Declarations updated. * txr.1: Updated.
* shuffle/nshuffle: eliminate wasteful vector copy.Kaz Kylheku2020-12-291-1/+1
| | | | | | * lib.c (nshuffle): When shuffling the vector that was converted from the list, use nshuffle rather shuffle, because it's a temporary, non-shared object we can mutate.
* printer: no leading zeros in hex chars.Kaz Kylheku2020-11-171-9/+6
| | | | | | | | * lib.c (obj_print_impl): Drop the complicated logic for printing a character as 2, 4 or 6 hex digits. All characters that must print using the #\x notation are jus printed using the ~X format specifier with no precision or leading zeros, which will use just as many digits as are required.
* env: move function to sysif.cKaz Kylheku2020-10-161-35/+1
| | | | | | | | | | | | | | | | | * lib.c (env_list): Static variable removed; now appears in sysif.c (env): Function removed; now in sysif.c. (obj_init): Don't gc-protect env_list here any more. * lib.h (env): Declaration removed. * match.c: Must include "sysif.h" now for env. * sysif.c (env_list): Static variable moved here. (env): Function moved here. (sysif_init): env_list gc-protected here. * sysif.h (env): Declared.
* time: move time functions out of lib.c into time.c.Kaz Kylheku2020-10-071-454/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Makefile (OBJS): Add new time.o. * eval.c (eval_init): Registration of time functions is removed from here; it is done in time_init now, in time.c. * hash.c: Must #include "time.h" now. * lib.c (time_s, time_local_s, time_utc_s, time_string_s, time_parse_s, year_s, month_s, day_s, hour_s, min_s, sec_s, dst_s, gmtoff_s, zone_s): Variable definitions removed. These are now in time.c. Also declared in time.h. (time_sec, time_sec_usec, gmtime_r, localtime_r, string_time, time_string_local, time_string_utc, broken_time_list, tm_to_time_struct, broken_time_struct, time_fields_local, time_fields_utc, time_struct_local, time_struct_utc, time_fields_to_tm, time_struct_to_tm, make_time_impl, make_time, epoch_tm, strptime_wrap, time_parse, setenv, unsetenv, timegm_hack, make_time_utc, time_meth, time_string_meth, time_parse_meth, time_parse_local, time_parse_utc): Functions removed. These are now in time.c. (time_init): Removed, and now in time.c as an external function. * lib.h (time_sec, time_sec_usec, time_string_local, time_string_utc, time_fields_local, time_fields_utc, time_struct_local, time_struct_utc, make_time, make_time_utc, time_parse, time_parse_local, time_parse_utc): Declarations removed. Now in time.h. * rand.c: Must #include "time.h" now. * time.c: New file. * time.h: New file.
* New function: reject.Kaz Kylheku2020-09-011-0/+45
| | | | | | | | | | | * eval.c (eva_init): Register reject intrinsic. * lib.c (appendl): New static function. (reject): New function. * lib.h (reject): Declared. * txr.1: Documented.
* Remove unnecessary forward declarations.Kaz Kylheku2020-08-171-2/+0
| | | | | | * lib.c (length_proper_list): Forward decl removed. * match.c (do_match_line): Likewise.
* cygwin: bugs in string catenation and splitting.Kaz Kylheku2020-08-071-4/+4
| | | | | | | | | | | | | | | | | | This looks like it originates in June 19, 2019 commit 28c6225fec6ce999806e9c077f08ed0e668646c4, before Version 218. The commit introduced the ability to use a character object as a separator in cat_str and split_str_keep. The implementation was broken as written for Cygwin. This finally showed up for me today as a failure in the new in6addr-str test cases. By chance, I noticed at the same time that tab completion in the listener was acting strangely on packag prefix symbols; that issue also went away with this fix. * lib.c (cat_str, vscat, scat3, split_str_keep): We must use wref on the array initialized using the wini macro, because on Cygwin, the string starts at [1] not [0].
* Change noreturn to NORETURN.Kaz Kylheku2020-08-071-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The noreturn macro is respelled to harmonize with the upper-case INLINE and NOINLINE. * lib.h (noreturn): Rename to NORETURN. * arith.c (not_number, not_integer, invalid_ops, invalid_op): Declaration updated. * arith.c (do_mp_error): Likewise. * eval.c (eval_error, no_bindable_error, dotted_form_error): Likewise. * eval.h (eval_error): Likewise. * lib.c (unsup_obj, callerror, wrongargs): Likewise. * match.c (sem_error): Likewise. * stream.c (unimpl, unimpl_put_string, unimpl_put_char, unimpl_put_byte, unimpl_get_line, unimpl_get_char, unimpl_get_byte, unimpl_unget_char, unimpl_unget_byte, unimpl_put_buf, unimpl_fill_buf, unimpl_seek, unimpl_truncate, unimpl_get_sock_family, unimpl_get_sock_type, unimpl_get_sock_peer, unimpl_set_sock_peer): Likewise. * struct.c (no_such_struct, no_such_slot, no_such_static_slot): Likewise. * unwind.h (jmp_restore, uw_throw, uw_throwf, uw_errorf, uw_errorfv, type_mismatch): Likewise.
* New sspl function.Kaz Kylheku2020-07-221-0/+5
| | | | | | | | | | | * eval (eval_init): Register sspl, an argument-reversed interface to split-str-set. * lib.c (sspl): New function. * lib.h (sspl): Declared. * txr.1: Documented.
* Support weak semantics in symbol packages.Kaz Kylheku2020-07-121-11/+12
| | | | | | | | | | | | | | | | | | | | | A package is weak if it holds weak references to symbols, meaning that if there are no references to a symbol other than its entry in a weak package, it can be removed from the package and reclaimed by the garbage collector. * eval.c (eval_init): Update registrations for make-package and sys:make-anon-package to reflect new optional argument. * lib.c (make_package_common): New argument weak. If it is true then both the hashes will have weak values. (make_package, make_anon_package): New optional argument weak. (obj_init): Add nil argument to calls to make_package. All the standard packages are regular, not weak. * lib.h (make_package, make_anon_package): Declarations updated. * txr.1: Documented.
* iter_item: bugfix/omission.Kaz Kylheku2020-07-081-0/+5
| | | | | * lib.c (iter_item): Fix neglect in this function to check for an oop iterator and use its iter-item method.
* uref/qref: read-print consistency issue.Kaz Kylheku2020-07-081-4/+12
| | | | | | | | | | | | | | | | The printer for uref/qref doesn't check for symbols that contain digits in the name, and so for instance (qref a3 3a) comes out as a3.3a, which does not read back, due to looking like a cramped floating-point constant. It looks like the weakest rule we can make is that all symbols that can be preceded by a dot must not have a name starting with a digit. Thus (qref 3a b c) can render as 3a.b.c. But (qref a 3b c) must not render as a.3b.c; it must be (qref a 3b c). * lib.c (simple_qref_args_p): Enact the above rule. In all positions preceded by a dot, if the symbol starts with a digit, then return nil to indicate that the syntax must be rendered in the list form.
* uref/qref: printing bug.Kaz Kylheku2020-07-081-1/+1
| | | | | | | | | | | * lib.c (obj_print_impl): The simple_qref_args_p function is called with reversed values of pos. For uref, we want 1, because the first item occurs after the dot, and for qref we want 0, because the first item occurs before the dot. This mix up means that the degenerate syntax (qref X) incorrectly prints as just X instead of (qref X). Likewise, though harmlessly, (uref X) fails to render as .X, instead coming out as (uref X).
* list_seq: return lazy list, not eager.Kaz Kylheku2020-07-081-8/+18
| | | | | | | | | * lib.c (list_seq_func): New static function. (list_seq): Convert to lazy processing. The iterator is threaded through the lazy cons's car field, so we don't have to mutate the function's environment. * txr.1: Added note about list-seq producing a lazy list.
* New: protocol for iteration with structs.Kaz Kylheku2020-07-071-26/+171
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (seq_iterable): Return t if argument is a structure supporting the iter-begin method. (seq_iter_get_oop, seq_iter_peek_oop, seq_iter_get_fast_oop, seq_iter_peek_fast_oop): New static functions. (seq_iter_init_with_info): Handle COBJ case. If the COBJ is a structure which suports the iter-begin method, then retrieve the iterator object by calling it, and then prepare the iterator structure for either the fast or the canonical protocol based on whether the iterator supports iter-more. (seq_iter_mark): Mark the iter member if the iterator is a struct object. (iter_begin): Rearrange tests here to check object type first before sequence kind. If the object is a structure supporting the iter-begin method, then call it and return its value. (iter_more, iter_step): Check for struct object with corresponding special methods and return. (iter_reset): Similar change like in iter_begin. We check for the iter-reset special method and try to use it, otherwise fall back on the regular iter_begin logic. * lib.h (struct seq_iter): New member next of the ul union for caching the result of a peek operation. * struct.c (iter_begin_s, iter_more_s, iter_item_s, iter_step_s, iter_reset_s): New symbol variables; (special_sym): Pointers to new symbol variables added to array. (struct_init): New symbol variables initialized. (get_special_required_slot): New function. * struct.h (iter_begin_s, iter_more_s, iter_item_s, iter_step_s, iter_reset_s): Declared. (enum special_slot): New enum members iter_begin_m, iter_more_m, iter_item_m, iter_step_m, iter_reset_m. (get_special_required_slot): Declared. * txr.1: Documented. * tests/012/oop-seq.expected: New file. * tests/012/oop-seq.tl: New file.
* seq_iter: reverse order of some tests.Kaz Kylheku2020-07-061-131/+129
| | | | | | | | | | | | | * lib.c (seq_iter_rewind, seq_iter_init_with_info): Reverse the order in which we perform some type tests. We check for some special types first, and then for the sequence kind. These situations are mutually exclusive now, so the order doesn't matter. The plan is to introduce the ability for a structure object to be iterable with special methods. Such an object won't necessarily be a sequence (seq_info may identify it as SEQ_NOTSEQ). This code will be prepared for it becuase it's now checking for the type first, before the sequence kind.
* New function: iterable.Kaz Kylheku2020-07-021-4/+43
| | | | | | | | | | | | * eval.c (eval_init): Register iterable intrinsic. * lib.c (seq_iterable): New static function. (nullify): Use seq_iterable to simplify function. (iterable): New function. * lib.h (iterable): Declared. * txr.1: Documented.
* c_num: now takes self argument.Kaz Kylheku2020-06-291-147/+198
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The c_num and c_unum functions now take a self argument for identifying the calling function. This requires changes in a large number of places. In a few places, additional functions acquire a self argument. The ffi module has the most extensive example of this. Some functions mention their name in a larger string, or have scattered literals giving their name; with the introduction of the self local variable, these are replaced by references to self. In the following changelog, the notation TS stands for "take self argument", meaning that the functions acquires a new "val self" argument. The notation DS means "define self": the functions in question defines a self variable, which they pass down. The notation PS means that the functions pass down an existing self variable to functions that now require it. * args.h (args_count): TS. * arith.c (c_unum, c_num): TS. (toint, exptv): DS. * buf.c (buf_check_len, buf_check_alloc_size, buf_check_index, buf_do_set_len, replace_buf, buf_put_buf, buf_put_i8, buf_put_u8, buf_put_char, buf_put_uchar, buf_get_bytes, buf_get_i8, buf_get_u8, buf_get_cptr, buf_strm_get_byte_callback, buf_strm_unget_byte, buf_swap32, str_buf, buf_int, buf_uint, int_buf, uint_buf): PS. (make_duplicate_buf, buf_shrink, sub_buf, buf_print, buf_pprint): DS. * chskum.c (sha256_stream_impl, sha256_buf, crc32_buf, md5_stream_impl, md5_buf): TS. (chksum_ensure_buf, sha256_stream, sha256, sha256_hash, md5_stream, md5, md5_hash): PS. (crc32_stream): DS. * combi.c (perm_while_fun, perm_gen_fun_common, perm_str_gen_fun, rperm_gen_fun, comb_vec_gen_fun, comb_str_gen_fun, rcomb_vec_gen_fun, rcomb_str_gen_fun): DS. * diff.c (dbg_clear, dbg_set, dbg_restore): DS. * eval.c (do_eval, gather_free_refs, maprodv, maprendv, maprodo, do_args_apf, do_args_ipf): DS. (op_dwim, me_op, map_common): PS. (prod_common): TS. * ffi.c (struct txr_ffi_type): release member TS. (make_ffi_type_pointer): PS and release argument TS. (ffi_varray_dynsize, ffi_array_in, ffi_array_put_common, ffi_array_get_common, ffi_varray_in, ffi_varray_null_term): PS. (ffi_simple_release, ffi_ptr_in_release, ffi_struct_release, ffi_wchar_array_get, ffi_array_release_common, ffi_array_release, ffi_varray_release): TS. (ffi_float_put, double_put, ffi_be_i16_put, ffi_be_u16_put, ffi_le_i16_put, ffi_le_u16_put, ffi_be_i32_put, ffi_be_u32_put, ffi_le_i32_put, ffi_sbit_put, ffi_ubit_put, ffi_buf_d_put, make_ffi_type_array, make_ffi_type_enum, ffi_type_compile, make_ffi_type_desc, ffi_make_call_desc, ffi_call_wrap, ffi_closure_dispatch_save, ffi_put_into, ffi_in, ffi_get, ffi_put, carray_set_length, carray_blank, carray_buf, carray_buf_sync, carray_cptr, carray_refset, carray_sub, carray_replace, carray_uint, carray_int): PS. (carray_vec, carray_list): DS. * filter.c (url_encode, url_decode, base64_stream_enc_impl): DS. * ftw.c (ftw_callback, ftw_wrap): DS. * gc.c (mark_obj, gc_set_delta): DS. * glob.c (glob_wrap): DS. * hash.c (equal_hash, eql_hash, eq_hash, do_make_hash, hash_equal, set_hash_traversal_limit, gen_hash_seed): DS. * itypes.c (c_i8, c_u8, c_i16, c_u16, c_i32, c_u32, c_i64, c_u64, c_short, c_ushort, c_int, c_uint, c_long, c_ulong): PS. * lib.c (seq_iter_rewind): TS and becomes internal. (seq_iter_init_with_info, seq_setpos, replace_str, less, replace_vec, diff, isec, obj_print_impl): PS. (nthcdr, equal, mkstring, mkustring, upcase_str, downcase_str, search_str, sub_str, cat_str, scat2, scat3, fmt_join, split_str_keep, split_str_set, trim_str, int_str, chr_int, chr_str, chr_str_set, vector, vecref, vecref_l, list_vec, copy_vec, sub_vec, cat_vec, lazy_str_put, lazy_str_gt, length_str_ge, length_str_lt, length_str_le, cptr_size_hint, cptr_int, out_lazy_str, out_quasi_str, time_string_local_time, time_string_utc, time_fields_local_time, time_fields_utc, time_struct_local, time_struct_utc, make_time, time_meth, time_parse_meth): DS. (init_str, cat_str_init, cat_str_measure, cat_str_append, vscat, time_fields_to_tm, time_struct_to_tm, make_time_impl): TS. * lib.h (seq_iter_rewind): Declaration removed. (c_num, c_unum, init_str): Declarations updated. * match.c (LOG_MISMATCH, LOG_MATCH): PS. (h_skip, h_coll, do_output_line, do_output, v_skip, v_fuzz, v_collect): DS. * parser.c (parser, circ_backpatch, report_security_problem, hist_save, repl, lino_fileno, lino_getch, lineno_getl, lineno_gets, lineno_open): DS. (parser_set_lineno, lisp_parse_impl): PS. * parser.l (YY_INPUT): PS. * rand.c (make_random_state): PS. * regex.c (print_rec): DS. (search_regex): PS. * signal.c (kill_wrap, raise_wrap, get_sig_handler, getitimer_wrap, setitimer_wrap): DS. * socket.c (addrinfo_in, sockaddr_pack, fd_timeout, to_connect, open_sockfd, sock_mark_connected, sock_timeout): TS. (getaddrinfo_wrap, dgram_set_sock_peer, sock_bind, sock_connect, sock_listen, sock_accept, sock_shutdown, sock_send_timeout, sock_recv_timeout, socketpair_wrap): DS. * stream.c (generic_fill_buf, errno_to_string, stdio_truncate, string_out_put_string, open_fileno, open_command, base_name, dir-name): DS. (unget_byte, put_buf, fill_buf, fill_buf_adjust, get_line_as_buf, formatv, put_byte, test_set_indent_mode, test_neq_set_indent_mode, set_indent_mode, set_indent, inc_indent, set_max_length, set_max_depth, open_subprocess, run ): PS. (fds_subst, fds_swizzle): TS. * struct.c (make_struct_type, super, umethod_args_fun): PS. (method_args_fun): DS. * strudel.c (strudel_put_buf, strudel_fill_buf): DS. * sysif.c (errno_wrap, exit_wrap, usleep_wrap, mkdir_wrap, ensure_dir, makedev_wrap, minor_wrap, major_wrap, mknod_wrap, mkfifo_wrap, wait_wrap, wifexited, wexitstatus, wifsignaled, wtermsig, wcoredump, wifstopped, wstopsig, wifcontinued, dup_wrap, close_wrap, exit_star_wrap, umask_wrap, setuid_wrap, seteuid_wrap, setgid_wrap, setegid_wrap, simulate_setuid_setgid, getpwuid_wrap, fnmatch_wrap, dlopen_wrap): DS. (chmod_wrap, do_chown, flock_pack, do_utimes, poll_wrap, setgroups_wrap, setresuid_wrap, setresgid_wrap, getgrgid_wrap): PS. (c_time): TS. * sysif.h (c_time): Declaration updated. * syslog.c (openlog_wrap, syslog_wrap): DS. * termios.c (termios_pack): TS. (tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap, tcdrain_wrap, tcflush_wrap, tcflow_rap, encode_speeds, decode_speeds): DS. * txr.c (compato, array_dim, gc_delta): DS. * unwind.c (uw_find_frames_by_mask): DS. * vm.c (vm_make_desc): PS. (vm_make_closure, vm_swtch): DS.
* New functions: list-seq, ved-seq and str-seq.Kaz Kylheku2020-06-281-0/+46
| | | | | | | | | | | | | | These functions convert any iterable to a list, vector or string. * eval.c (eval_init): Registered list-seq, vec-seq and str-seq intrinsics. * lib.c (list_seq, vec_seq, str_seq): New functions. * lib.h (list_seq, vec_seq, str_seq): Declared. * txr.1: Documented.
* itypes: remove silly itypes_little_endian.Kaz Kylheku2020-06-191-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Curiously, the itypes_little_endian variable was introduced in April 2017, in a the first commit implementing buffers. The variable was initialized, but never referenced. About a month after that, I introduced HAVE_LITTLE_ENDIAN config.h macro, which is always present and defined as 0 or 1. This was used right away in the implementation of FFI bitfields, and later on in other FFI work. In spite of HAVE_LITTLE_ENDIAN, almost exactly a year after itypes_little_endian was introduced, I mistakenly put that variable to use instead of recognizing it as superfluous and removing it in favor of using HAVE_LITTLE_ENDIAN. That is what I'm doing now. * itypes.c (itypes_little_endian): Variable removed. (itypes_init): Function removed, since its only job is to initialize this variable. * itypesl.h (itypes_little_endian, itypes_init): Declarations removed. * lib.c (init): Call to itypes_init removed. * parser.c (read_file_common): Instead of itypes_little_indian, use HAVE_LITTLE_ENDIAN, which the configuration script always exists and is defined as 0 or 1.
* seq_iter_rewind: support iterables.Kaz Kylheku2020-06-051-0/+31
| | | | | | | This fixes cases like (isec 0..10 5..15). * lib.c (seq_iter_rewind): Handle the rewinding of non-sequence iterators (ranges, characters, numbers).
* nullify and empty: convert to seq_info.Kaz Kylheku2020-06-051-67/+28
| | | | | | | | | | | | | | | | | Issues: (nullify 1..1) doesn't return nil as it should, and (empty 1) fails. * lib.c (seq_info): Since we would like nullify to use seq_info, seq_info cannot call nullify. Transplant the probing of the nullify method out of nullify and into here. (nullify): Obtain a seq_info_t on the object. If it's not a sequence and is not range, then just return the object. Otherwise obtain a seq_iter_t sequence and peek whether it has a next item. (empty): Similarly, obtain an iterator and peek. Definition of empty is relocated to be next to nullify. * lib.h: Relocate declaration of empty, also.
* transpose: ensure variadic args are a list.Kaz Kylheku2020-06-051-3/+3
| | | | | | | | | * lib.c (transpose): Don't simply copy the input, but convert it to a list with tolist. The transposev function relies on mapcarv, and that function now doesn't simply pull out the trailing object from the args. It processes the args as args, and a non-list causes problems there, such as args_count reporting the wrong value.
* seq_iter: support reverse iteration for ranges.Kaz Kylheku2020-06-041-28/+110
| | | | | | | | | | | | | | | | | | | | | | * lib.h (seq_iter_t): Add some union members to ui and ul for use with ranges. The purpose of this is to have separate naming for the iteration variables for ranges. * lib.c (seq_iter_get_range_cnum, seq_iter_peek_range_cnum, seq_iter_get_range_chr, seq_iter_peek_range_chr, seq_iter_get_range_bignum, seq_iter_peek_range_bignum): Use new union member names for clarity. (seq_iter_get_rev_range_cnum, seq_iter_peek_rev_range_cnum, seq_iter_get_rev_range_chr, seq_iter_peek_rev_range_chr, seq_iter_get_rev_range_bignum, seq_iter_peek_rev_range_bignum): New static functions. (seq_iter_with_init_info): Drop obj argument since the si argument has the object. Add handling for empty and reversed ranges. Also convert unbounded ranges like N..t and N..: to just N, recursively. Use new union member names. (seq_iter_init, seq_iter_init_with_rewind, iter_begin, iter_reset): Follow elimination of argument in seq_iter_init_with_info.
* seq_iter: null list object if rewind not needed.Kaz Kylheku2020-06-041-6/+14
| | | | | | | | | | | | * lib.c (seq_iter_init_with_info): Take new Boolean argument indicating whether the iterator needs to support the rewind operation. If this is false, and the object is a list, then we clobber the object, in order to eliminate the GC root. (seq_iter_init, iter_begin, iter_reset): Pass 0 for the new Boolean parameter. (seq_iter_init_with_rewind): New function. (diff, isec): Use seq_iter_init_with_rewind to request an iterator with rewind support for the second sequence.
* Convert mapping functions to new iterators.Kaz Kylheku2020-06-031-39/+24
| | | | | | | | | | | | | | | | | * eval.c (get_iter_f): Renamed to iter_from_binding_f. (iter_begin_f, iter_more_f, iter_item_f, iter_step_f): New global variables. (op_each): Follow rename of get_iter_f. (mapcarv, mappendv, lazy_mapcar_func, lazy_mapcar, lazy_mapcarv_func, lazy_mapcarv, mapdov, prod_common): Convert from car/cdr/null-test iteration to iter-begin. (eval_init): gc-protect and initialize new variables. * lib.c (mapcar_listout, mappend, mapdo): Convert to seq_iter iteration. List argument renamed to seq. (mapcar): List argument renamed to seq. * lib.h: Declarations updated with renamed arguments.
* seq_iter: integers and ranges become iterable.Kaz Kylheku2020-06-031-14/+172
| | | | | | | | | | | | | | | | | | | | | I think with the iter-begin API, we have the the "Maxwell's Equations of Iteration". This not only works well for conses, but it extends to numbers and ranges. * lib.h (seq_iter_t): New union member ul, containing a new member lim. existing len member moved into ul union. * lib.c (seq_iter_get_vec, seq_iter_peek_vec): Adjust access of len, now wrapped in union. (seq_iter_get_range_cnum, seq_iter_peek_range_cnum, seq_iter_get_range_chr, seq_iter_peek_range_chr, seq_iter_get_range_bignum, seq_iter_peek_range_bignum, seq_iter_get_chr, seq_iter_peek_chr, seq_iter_get_num, seq_iter_peek_num): New static functions. (seq_iter_init_with_info): Support RNG object, further classifying the iteration based on the type of the from element. Support numbers and characters as iterable. (iter_begin, iter_more, iter_item, iter_step, iter_reset): Support numbers directly as unencapsulated iterators.
* New style iteration functions.Kaz Kylheku2020-06-021-2/+109
| | | | | | | | | | | | | | | | | | | | | | | | iter-begin provides a paradigm for iteration that is more compatible with lists. If the sequence is a list, then the list itself is returned as the iterator, and the other functions are basicaly wrappers for car/cdr and null testing. Yet the API is defined in such a way that other objects can be iterated with good efficiency, at the cost of allocating a new iterator object (which can be re-used). * eval.c (eval_init): Register iter-begin, iter-more, iter-item, iter-step and iter-reset. * lib.c (seq_iter_init_with_info): New static function. (seq_iter_init): Now a thin wrapper for seq_iter_init_with_info. (iter_begin, iter_more, iter_item, iter_step, iter_reset): New functions. * lib.h (iter_begin, iter_more, iter_item, iter_step, iter_reset): New functions. * txr.1: Documented.
* Replace trivial format(nil, ...) with simpler ops.Kaz Kylheku2020-05-301-0/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * gencadr.txr (cadr_register): Use scat2 to glue two strings. * cadr.c: Regenerated. * lib.c (scat2, scat3): New functions. * lib.h (scat2, scat3): Declared. * liblib.c (place_instantiate, ver_instantiate, ifa_instantiate, txr_case_instantiate, with_resources_instantiate, path_test_instantiate, struct_instantiate, with_stream_instantiate, hash_instantiate, except_instantiate, type_instantiate, yield_instantiate, sock_instantiate, termios_instantiate, awk_instantiate, build_instantiate, trace_instantiate, getopts_instantiate, package_instantiate, getput_instantiate, tagbody_instantiate, pmac_instantiate, error_instantiate, keyparams_instantiate, ffi_instantiate, doloop_instantiate, stream_wrap_instantiate, asm_instantiate, compiler_instantiate, debugger_instantiate, op_instantiate, save_exe_instantiate, defset_instantiate, copy_file_instantiate): Use scat2 to glue two strings instead of format. * parser.c (find_matching_syms, hist_save, repl): Replace trivial uses of format with scat2 or scat3. * sysif.c (ensure_dir): Likewise. * txr.c (get_self_path, substitute_basename, sysroot, sysroot_init, parse_once_noerr, read_compiled_file_noerr, read_eval_stream_noerr): Likewise. * unwind.c (uw_unwind_to_exit_point): Likewise.
* quasistrings: reduce consing.Kaz Kylheku2020-05-301-6/+34
| | | | | | | | | | | | | | | | | | | 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.
* search, rsearch: rewrite using seq_info and bugfix.Kaz Kylheku2020-05-251-114/+86
| | | | | | | | | | | | | | | * lib.c (seq_getpos, seq_setpos): New functions. * lib.h (seq_getpos, seq_setpos): Declared. (search_list, rsearch_list): Static functions removed. (search_common): New static function. (search, contains, rsearch): These functions are now trivial wrappers around search_common. A requirement problem is fixed in rsearch: when the key is empty, the length of sequence is returned rather than zero, because zero is obviously not the right most place where an empty key matches. * txr.1: Documentation updated.
* update: convert to seq_info.Kaz Kylheku2020-05-251-14/+11
| | | | | * lib.c (update): Function converted to seq_info classification instead of switching on type.
* rsearch: fix broken.Kaz Kylheku2020-05-251-4/+2
| | | | | | | | | | | The rsearch function is completely broken, returning incorrect values. * lib.c (search_list, rsearch_list): Update the position in the increment part of the loop. This fix only affects research, but the code is copy-and-paste, so it's good to keep them the same, and the position of the pos update is a code smell regardless.
* search/rsearch: wrong object in bad key diagnostic.Kaz Kylheku2020-05-251-2/+2
| | | | | * lib.c (search_list, rsearch_list): When the key has a bad type, don't report the seq object in its place.
* lib: combine cat_str and vscat implementations.Kaz Kylheku2020-05-241-105/+91
| | | | | | | | | | | | | | | | | | | | | | | The vscat function is white-box copy of cat_str, with just the iteration over the inputs done differently, and without the support for separators that are characters instead of strings (which was added to cat_str after vscat was forked. In this patch, the common logic underlying both functions is factored out into a small ad-hoc "struct cat_str" object which maintains the state and provides the operations to measure the pieces of the string, allocate the space, copy the pieces together and produce the resulting object. The motivation here isn't just to reduce duplication. I would like a more efficient function for catenating strings which takes a "struct args *", not requiring a list to be consed up. * lib.c (struct cat_str): New struct type. (cat_str_init, cat_str_measure, cat_str_alloc, cat_str_append, cat_str_get): New static functions. (cat_str, vscat): Considerably shorten by using the above functions.