summaryrefslogtreecommitdiffstats
path: root/lib.h
Commit message (Collapse)AuthorAgeFilesLines
* New accessor: mref.Kaz Kylheku2023-11-151-0/+1
| | | | | | | | | | | | | | * 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/+2
| | | | | | | | | | | | | | | | | | | | | | 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.
* New hist-sort function.Kaz Kylheku2023-09-251-1/+2
| | | | | | | | | | | | | | | * 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-0/+2
| | | | | | | | | | | | | | | * 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-46/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* New function: str-esc.Kaz Kylheku2023-09-011-0/+1
| | | | | | | | | | * lib.[ch] (str_esc): New function. * eval.c (eval_init): str-esc intrinsic registered. * tests/015/esc.tl: New file. * txr.1: Documented.
* New feature: local symbol renaming.Kaz Kylheku2023-08-101-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Math library: add numerous C99 functions.Kaz Kylheku2023-07-151-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * configure: Detect all the new functions, with separate tests for the unary and binary ones. * arith.c (cbrt_s, erf_s, erfc_s, exp10_s, exp2_s, expm1_s, gamma_s, j0_s, j1_s, lgamma_s, log1p_s, logb_s, nearbyint_s, rint_s, significand_s, tgamma_s, y0_s, y1_s, copysign_s, drem_s, fdim_s, fmax_s, fmin_s, hypot_s, jn_s, ldexp_s, nextafter_s, remainder_s, scalb_s, scalbln_s, yn_s, r_copysign_s, r_drem_s, r_fdim_s, r_fmax_s, r_fmin_s, hypot_s, r_jn_s, r_ldexp_s, r_nextafter_s, r_remainder_s, r_scalb_s, scalbln_s, r_yn_s): New symbol variables. (not_available): New static function. (cbrt_wrap, erf_wrap, erfc_wrap, exp10_wrap, exp2_wrap, expm1_wrap, gamma_wrap, j0_wrap, j1_wrap, lgamma_wrap, log1p_wrap, logb_wrap, nearbyint_wrap, rint_wrap, significand_wrap, tgamma_wrap, y0_wrap, y1_wrap, copysign_wrap, drem_wrap, fdim_wrap, fmax_wrap, fmin_wrap, hypot_wrap, jn_wrap, ldexp_wrap, nextafter_wrap, remainder_wrap, scalb_wrap, scalbln_wrap, yn_wrap): New static functions. (arith_set_entries, arith_instantiate): New static functions. (arith_init): Initialize symbols and instantiate functions via autoload mechanism. In a program that doesn't use the functions, we suffer only the overhead of interning the symbols. * lib.h (UNUSED): New macro for GCC unused attribute. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New @(push) directive.Kaz Kylheku2023-06-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | @(push) is like @(output), but feeds back into input. Use carefully. * parser.y (PUSH): New token. (output_push): New nonterminal symbol. (output_clause): Handle OUTPUT or PUSH via output_push. Some logic moved to output_helper. (output_helper): New function. Transforms both @(output) and @(push) directives. Checks both for valid keywords; push has only :filter. * parser.l (grammar): Recognize @(push similarly to other directives. * lib.[ch] (push_s): New symbol variable. * match.c (v_output_keys): Internal linkage changes to external. (v_push): New function. (v_parallel): We must fix the max_line algorithm not to use an initial value of zero, because lines can go negative thanks to @(push). We end up rejecting the pushed data. (v_collect): We can no longer assert that the data line number doesn't retreat. (dir_tables_init): Register push directive in table of vertical directives. * match.h (append_k, continue_k, finish_k): Existing symbol variables declared. (v_output_keys): Declared. * y.tab.c.shipped, * y.tab.h.shipped, * lex.yy.c.shipped: Updated. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New functions keep-keys-if, separate-keys.Kaz Kylheku2023-06-071-0/+2
| | | | | | | | | | | * lib.[ch] (keep_keys_if, separate_keys): New functions. * eval.c (eval_init): keep-keys-if, separate-keys intrinsics registered. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* gc: fix bad c++ casts.Kaz Kylheku2023-06-031-2/+2
| | | | | | | | | | This C++ regression snuck into in Version 286; I didn't check C++ compilation. * lib.h (container): Macro must use coerce not convert because mem_t * isn't void *. * gc.c (gc_prot_array_alloc): Likewise.
* gc: use single allocation for prot_array.Kaz Kylheku2023-05-021-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | * gc.c (prot_array): Add self pointer; arr member becomes flexible array. (prot_array_mark): We now check the handle itself for null, because the whole thing is freed. (prot_array_free): Function removed. (prot_array_ops): Wire cobj_destroy_free_op in place of prot_array_free. This fixes a memory leak because prot_array_free was not freeing the handle, only the array. (gc_prot_array_alloc): Fix to allocate everything in one swoop and store the self-pointer in the named member rather than arr[-1]. The self argument is not required; we drop it. The size argument cannot be anywhere near INT_PTR_MAX, because such an array wouldn't fit into virtual memory, so it is always safe to add a small value to the size. (prot_array_free): Obtain the self-pointer, and free the handle, replacing it with a null pointer. * gc.h (gc_prot_array_alloc): Declaration updated. * lib.c (ssort_vec): Don't pass self to gc_prot_array_alloc. * lib.h (container): New macro.
* sort: support stable sorting via ssort and snsort.Kaz Kylheku2023-05-021-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For array-like objecgts, these objects use an array-based merge sort, using an auxiliary array equal in size to the original array. To provide the auxiliary array, a new kind of very simple vector-like object is introduced into the gc module: protected array. This looks like a raw dynamic C array of val type, returned as a val *. Under the hood, there is a heap object there, which makes the array traversable by the garbage collector. The whole point of this exercise is to make the new mergesort function safe even if the caller-supplied functions misbehave in such a way that the auxiliary array holds the only references to heap objects. * gc.c (struct prot_array): New struct, (prot_array_cls): New static variable. (gc_late_init): Register COBJ class, retaining in prot_array_cls. (prot_array_mark, prot_array_free): New static functions. (prot_array_ops): New static structure. (prot_array_alloc, prot_array_free): New functions. * gc.h (prot_array_alloc, prot_array_free): Declared. * lib.c (mergesort, ssort_vec): New static function. (snsort, ssort): New functions. * lib.h (snsort, ssort): Declared. * tests/010/sort.tl: Cover ssort. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: arithp.Kaz Kylheku2023-03-261-0/+2
| | | | | | | | | | | | | | | | | | | * lib.h (arithp): Declared. (plus_s): Existing symbol declared. * arith.c (arithp): New function. * struct.h (special_slot): New enum member plus_m. * struct.c (special_sym): Register plus_s together as the [plus_m] entry of the array. * tests/016/arith.tl * tests/016/ud-arith.tl: Tests for arithp. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* fix --no-gen-gc configuration.Kaz Kylheku2023-01-201-3/+3
| | | | | | | | | | | | | | | | | | | This fixes only the build. I'm getting a crash in one test case, namely tests/010/json.tl. * lib.h (mut): Remove stray semicolon from definition. This semicolon compensates for the lack of a semicolon in txr.c, which becomes a syntax errror under no-gen-gc, when the other definition of mut is active. (mkloc, setcheck): Let's add casts of the object argument to void. This gets rid of a number of unused parameter errors in various functions that take an object parameter that is only used in the case of generational GC. * txr.c (txr_main): Add missing semicolon after mut call. * gc.c (gc_wrap): In the no CONFIG_GEN_GC case, cast argument full to void, since it is unused.
* Copyright year bump 2023.Kaz Kylheku2023-01-011-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, lex.yy.c.shipped, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, protsym.c, 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/debugger.tl, stdlib/defset.tl, stdlib/doloop.tl, stdlib/each-prod.tl, stdlib/error.tl, stdlib/except.tl, stdlib/ffi.tl, stdlib/getopts.tl, stdlib/getput.tl, stdlib/hash.tl, stdlib/ifa.tl, stdlib/keyparams.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 2023.
* lib: or2: define in GCC-specific way.Kaz Kylheku2022-10-261-1/+5
| | | | | | | | | * lib.h (or2): Define simply using the ?: operator from GNU C, eliminating the explicit temporary variable. (uses_or2): For GNU C, we make this a dummy, harmless declaration. If memory serves me, one of the few good ways to do that it without eliciting unused warnings is to declare an enum.
* strings: revert caching of hash value.Kaz Kylheku2022-10-081-3/+1
| | | | | | | | | | | | | | | Research indicates that this is something useful in languages that abuse strings for implementing symbols. We have interned symbols. * lib.h (struct string): Remove hash member. * lib.c (string_own, string, string_utf8, mkustring, string_extend, replace_str, chr_str_set): Remove all initializations and updates of the removed hash member. * hash.c (equal_hash): Do not cache string hash value.
* strings: take advantage of malloc_usable_sizeKaz Kylheku2022-10-061-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On platforms which have the malloc_usable_size function, we don't have to store the allocated size of an object; malloc provides us the allocated size (which may be larger than we requested). Here we take advantage of this for strings. And since we don't have to store the string allocated size any more, we use that field for something else: storing the hash code (for seed zero). This can speed up some hashing operations. * configure (have_malloc_usable_size): New variable. Configure test for have_malloc_usable size. We have to try several header files, too. We set the configure variable HAVE_MALLOC_USABLE_SIZE, and possibly HAVE_MALLOC_H or HAVE_MALLOC_NP_H. * lib.h (struct string): If HAVE_MALLOC_USABLE_SIZE is true, we define a member called hash insetad of alloc. Also, we change alloc to cnum. * lib.c: Include <malloc_np.h> if HAVE_MALLOC_NP_H is defined. (string_own, string, string_utf8, mkstring, mkustring, init_str, string_extend, string_finish, string_set_code, string_get_code, length_str, replace_str, chr_str_set): Fix code for both cases. On platforms with malloc_usable_size, we have the allocated size from malloc, so we don't have to retrieve it from the object or store it. Any operations which mutate the string must reset the hash field to zero; zero means "hash has not been calculated". * hash.c (equal_hash): Just retrive a string's hash value, if it is nonzero, otherwise calculate, cache it and return it. * gc.c (mark_obj): The alloc member of struct string is a machine integer now; no need to mark it.
* nan-boxing: warning fix for gcc 12.Kaz Kylheku2022-09-161-0/+2
| | | | | | | | | | gcc 12.2.0, targetting RISC-V, emitted a warning for the c_f function that the &u expression uses an uninitialized u, even though u is declared with an initializer. Code builds otherwise and tests pass. * lib.h (c_f): Also suppress and re-enable the -Wuninitialized option.
* nan-boxing: build on older gcc.Kaz Kylheku2022-09-161-7/+8
| | | | | | | | | | | | Older GCC 4.x versions do not support diagnostic pragmas in functions and don't have push pragmas for diagnostics. * arith.c (flo): Put the diagnostic disabling pragma stuff outside of the function. Instead saving and restoring the status with push and pop, we just disable the aliasing warning and re-instate it as a warning. * lib.h (c_f): Likewise.
* nan-boxing: use GCC pragmas to disable aliasing warnings.Kaz Kylheku2022-09-141-0/+7
| | | | | | | | | | | * arith.c (flo): The line of code which triggers the aliasing diagnostic is wrapped with GNU-C-specific pramgas that disable the diagnostic just for that line. * lib.h (c_f): Likewise. * configure: Drop the test which adds -Wno-strict-aliasing to the DIAG_FLAGS;
* Implement NaN boxing.Kaz Kylheku2022-09-131-17/+137
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On platforms with 64 bit pointers, and therefore 64-bit-wide TXR values, we can use a representation technique which allows double floating-point values to be unboxed. Fixnum integers are reduced from 62 bits to 50, and there is a little more complexity in the run-time type checking and dispatch which costs extra cycles. The support is currently off by default; it must be explicitly enabled with ./configure --nan-boxing. * lib.h (NUM_MAX, NUM_MIN, NUM_BIT): Define separately for NaN boxing. (TAG_FLNUM, TAG_WIDTH, NAN_TAG_BIT, NAN_TAG_MASK, TAG_BIGMASK, TAG_BIGSHIFT, NAN_FLNUM_DELTA): New preprocessor symbols. (enum type, type_t): The FLNUM enumeration constant moves to just after LIT, so that its value is the same as TAG_FLNUM. (struct flonum): Does not exist under NaN boxing. (union obj): No fl member under NaN boxing. (tag, is_ptr): Separately defined for NaN boxing. (is_flo): New function under NaN boxing. (tag_ex): New function. It's like tag, but identifies floating-point values as TAG_FLNUM. The tag function continues to map them to TAG_PTR, which is wrong under NaN boxing, but needed in order not to separately write tons of cases in the arith.c module. (type): Use tag_ex, so TAG_FLNUM is handled, if it exists. (auto_str, static_str, litptr, num_fast, chr, c_n, c_u): Different definition for NaN boxing. (c_ch, c_f): New function. (throw_mismatch): Attribute with NORETURN. (nao): Separate definition for NaN boxing. * lib.c (seq_kind_tab): Reorder initializer to follow enum reordering. (seq_iter_rewind): use c_n and c_ch functions, since type checking has been done in those cases. The self parameter is no longer needed. (iter_more): use c_ch on CHR object. (equal): Use c_f accessor to get double value rather than assuming there is a struct flonum representation. (stringp): Use tag_ex, otherwise a floating-point number is identified as TAG_PTR. (diff, isec, isecp): Don't pass removed self parameter to seq_iter_rewind. * arith.c (c_unum, c_dbl_num, c_dbl_unum, plus, minus, signum, gt, lt, ge, le, numeq, logand, logior, logxor, logxor_old, bit, bitset, tofloat, toint, width, c_num, c_fixnum): Extract floating-point value using c_f accessor. Handle CHR type separately from NUM because the storage representation is no longer identical; CHR values have a two bit tag over bits where NUM has ordinary value bits. NUM is tagged at the NaN level with the upper 14 bits being 0xFFFC. The remaining 50 bits are the value. (flo): Construct unboxed float under NaN boxing by taking image of double as a 64 bit value, and adding the delta offset, then casting to the val pointer type. (c_flo): Separate implementation for NaN boxing. (integerp, numberp): Use tag_ex. * buf.c (str_buf, buf_int): Separate CHR and NUM cases, like in numerous arith.c functions. * chksum.c (sha256_hash, md5_hash): Use c_ch accessor for CHR value. * hash.c (equal_hash, eql_hash): Handle CHR separately. Use c_f accessor for floating-point value. (eq_hash): Use tag_ex and handle TAG_FLNUM value under NaN boxing. Handle CHR separately from NUM. * ffi.c (ffi_float_put, ffi_double_put, carray_uint, carray_int): Handle CHR and NUM separately. * stream.c (formatv): Use c_f accessor. * configure: disable automatic selection of NaN boxing on 64 bit platforms, for now. Add test whether -Wno-strict-aliasing is supported by the compiler, performed only if NaN boxing is enabled. We need to disable this warning because it goes off on the code that reinterprets an integer as a double and vice versa.
* Define bit width of NUM type in one place.Kaz Kylheku2022-09-121-0/+1
| | | | | | | | | | | | * lib.h (NUM_BIT): New preprocessor symbol. * arith.c (CNUM_BIT): Preprocessor symbol removed; this same quantity is already known as PTR_BIT in lib.h. (mul, square): Replace CNUM_BIT with PTR_BIT. (comp_trunc, logtrunc, sign_extend, ash): Replace num_bits with NUM_BIT. * struct.c (struct_inst): Replace calculation with NUM_BIT.
* New macro: close-lazy-streams.Kaz Kylheku2022-08-281-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | * lib.c (lazy_stream_s): New symbol variable. (lazy_streams_binding): New static variable. (lazy_stream_register): New static function (lazy_stream_cons): If the stream is associated with a lazy cons, register it with lazy_stream_register. (obj_init): gc-protect lazy_streams_binding variable. Intern the sys:*lazy-streams* symbol. * lib.h (lazy_streams_s): Declared. * eval.c (eval_init): Register sys:*lazy-streams* special variable. * stdlib/getput.tl (close-lazy-streams): New macro. * autoload.c (getput_set_entries): Trigger autload on close-lazy-streams symbol. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: search-allKaz Kylheku2022-08-171-0/+1
| | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): search-all intrinsic registered. * lib.c (search_common): New Boolean argument all, indicating whether all positions are to be returned. We must handle this in the two places where empty key and sequence are handled, and also in the main loop. A trick is used: the found variable is now bound by list_collect_decl, but not used for collecting unless all is true. (search, rsearch, contains): Pass 0 for all argument of search_common. (search_all): New function. * lib.h (search_all): Declared. * tests/012/seq.tl: New tests. * txr.1: Documented. * stdlib/doc-syms.tl: Regenerated.
* New function: count.Kaz Kylheku2022-07-181-0/+1
| | | | | | | | | | | | | | | | The general count function, with keyfun and testfun, is noticeably absent. Let's implement it. * lib.[ch] (count): New function. * eval.c (eval_init): Register count intrinsic. * tests/012/seq.tl: Some tests for count. * txr.1: Add count to count-if section. Revise documentation based on pos/pos-if. * stdlib/doc-syms.tl: Updated.
* New function: strKaz Kylheku2022-06-121-0/+1
| | | | | | | | | | | | | | | The str function is like mkstring but allows a fill pattern to be specified. * eval.c (eval_init): str intrinsic registered. * lib.[ch[ (str): New function. * tests/015/str.tl: New file. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New: spln and tokn functions.Kaz Kylheku2022-05-301-0/+2
| | | | | | | | | | | | | | | Instead of trying to work the new count parameter into the spl and tok functions, it's better to make new ones. * eval.c (eval_init): spln and tokn intrinsics registered. * lib.[ch] (spln, tokn): New functions. * tests/015/split.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* tok-str: takes count argument.Kaz Kylheku2022-05-281-1/+1
| | | | | | | | | | | | | | * eval.c (eval_init): Update registration of tok-str. * lib.c (tok_str): New argument, count_opt. Implemented in the compat 155 case; what the heck. (tok): Pass nil to new parameter of tok_str. * lib.h (tok_str): Declaration updated. * tests/015/split.tl: New tests. * txr.1: Documented.
* split-str: new count parameter.Kaz Kylheku2022-05-171-1/+1
| | | | | | | | | | | | | | | | | | * eval.c (eval_init): Fix up registration of split-str to account for new parameter. * lib.c (split_str_keep): Implement new optional count argument. (spl): Pass nil value to split_str_keep for new argument. I'd like this function to benefit from this argument also, but the design isn't settled. (split_str): Pass nil argument to split_str_keep. * lib.h (split_str_keep): Declaration updated. * tests/015/split.tl: New tests. * txr.1: Documented.
* New function: isecp.Kaz Kylheku2022-03-301-0/+1
| | | | | | | | | | | | | | | | | * eval.c (eval_init): Register isecp intrinsic. * lib.c (isecp): New function. * lib.h (isecp): Declared. * stdlib/compiler.tl (lambda-apply-transform, dump-compiled-objects): Use isecp instead of isec, since the actual intersection of symbols isn't needed, only whether it exists. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: partition-if.Kaz Kylheku2022-02-231-0/+1
| | | | | | | | | | | | | | | | * eval.c (eval_init): Register partition-if intrinsic. * lib.c (partition_if_countdown_funv, partition_if_func): New functions. (partition_if): New function. * lib.h (partition_if): Declared. * tests/012/seq.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New functions: find-max-key and find-min-key.Kaz Kylheku2022-02-211-0/+2
| | | | | | | | | | | | | * eval.c (eval_init): Register find-max-key and find-min-key intrinsics. * lib.c (find_max_key, find_min_key): New functions. * lib.h (find_max_key, find_min_key): Declared. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* Fix some issues found by ubsan.Kaz Kylheku2022-02-141-0/+4
| | | | | | | | | | | | | | | | * lib.h (num_fast): Under HAVE_UBSAN, avoid left shifting a negative value, which is diagnosed by ubsan (by default), but is otherwise a documented GCC extension that behaves sanely in the manner one would expect on two's complement machines. * mpi/mpi.c (s_mp_mul_2d): Fix instance of undefined shift equal to the width of the type. This occurs in the case when d == 0. In that case, we try to calculate a 32 or 64 bit full mask by shifting 1 to the left that many times and then subtracting 1. However, the entire code for the fractional shift is not necessary in that case and may be skipped. I'm also removing the unnecesary s_mp_clamp call. If the number is clamped on entry into the function, it stays clamped.
* Few adjustments to no-implicit-conversion patch.Kaz Kylheku2022-02-141-0/+6
| | | | | | | | | | | | | | | | | | | | * lib.h (c_u): New inline function: unsafe conversion to ucnum, analogous to c_n for cnum. * hash.c (equal_hash, hash_iter_init): Use UINT_PTR_MAX instead of convert(ucnum, -1). (eql_hash): mp_hash returns unsigned long, so shouldn't require a cast to go to the uint_ptr_t. The types are of the same size, or at worst it is a widening. Also replace convert(ucnum, -1) by UINT_PTR_MAX here. Combining the TAG_CHR and TAG_NUM cases, and using c_u, which is more efficient since c_chr and c_num are non-inlined functions which redundantly check type. We no longer need a self variable in this function. (eq_hash): Same TAG_CHR and TAG_NUM changes as eql_hash. * regex.c (char_set_add): Reformat change to avoid line break across assignment.
* New function: copy-cptr.Kaz Kylheku2022-01-281-0/+1
| | | | | | | | | | | | | | | * eval.c (eval_init): copy-cptr intrinsic registered. * lib.c (copy_cptr): New function. (copy): Use copy_cptr for CPTR objects. * lib.h (copy_cptr): Declared. * tests/017/ffi-misc.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* Remove numerous unused global functions.Kaz Kylheku2022-01-231-9/+0
| | | | | | | | | | | | | | | | | | | | | | | * eval.[ch] (lookup_global_var_l): Remove. * itypes.[ch] (c_schar): Likewise. * lib.[ch] (null_list, rcyc_list, gequal, func_n6v, func_n7v, func_n8v, do_pa_123_23, pa_123_23, orf, aconsql_new_c): Likewise. (obj_init): Remove references to null_list. * mpi/mpi-config.h (MP_FOR_TXR): New preprocessor symbol, defined as 1. * mpi/mpi.c (mp_get_prec, mp_set_prec, mp_init_array, mp_clear_array, mp_set_word, mp_exptmod_d, mp_cmp_d, mp_cmp_mag, mp_cmp_int, mp_lcm, mp_xgcd, mp_invmod, mp_char2value): Exclude using #if !MPI_FOR_TXR, rather than remove. We don't bother excluding the declarations in the header. * utf8.[ch] (w_freopen): Remove.
* lib: new functions nand, nor, nandf and norf.Paul A. Patience2022-01-221-0/+2
| | | | | | | | | | | | | | * eval.c (me_nand, me_nor, nor_fun, nand_fun): New functions. (eval_init): Register new intrinsics. * lib.c (nandv, norv): New functions. * lib.h (nandv, norv): Declared. * txr.1: Documented, along with trivial fixes to the descriptions of and, or, andf, orf and notf. * stdlib/doc-syms.tl: Updated.
* Copyright year bump 2022.Kaz Kylheku2022-01-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *LICENSE, LICENSE-CYG, METALICENSE, 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, 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/debugger.tl, stdlib/defset.tl, stdlib/doloop.tl, stdlib/each-prod.tl, stdlib/error.tl, stdlib/except.tl, stdlib/ffi.tl, stdlib/getopts.tl, stdlib/getput.tl, stdlib/hash.tl, stdlib/ifa.tl, stdlib/keyparams.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 2022.
* num_ex: eliminate ill-considered cast.Kaz Kylheku2022-01-061-1/+1
| | | | | | | * lib.h (num_ex): Remove the cast to ucnum, which will cause this macro to misbehave for negative arguments. For instance, -1 > (ucnum) INT_PTR_MAX will compare as true! The -1 gets converted to the unsigned type and becomes UINT_PTR_MAX.
* sysif: rlim constants: use signed/unsigned-agnostic macro.Kaz Kylheku2022-01-021-0/+2
| | | | | | | | | | | | * lib.h (num_ex): New macro. Uses unum if the argument is out of range for the signed type. Thus we can use this with unsigned constants that would wrap negative if passed to num. This is useful if some type in a system header file might be signed or unsigned. * sysif.c (sysif_init): Use num_ex for the RLIM_* constants. I'm observing values of -1 which should really be large, positive values in the rlim_t type, that being unsigned.
* The pairlis function comes to TXR Lisp.Kaz Kylheku2021-12-221-0/+1
| | | | | | | | | | | | * eval.c (eval_init): Register pairlis intrinsic. * lib.c, lib.h (pairlis): New function. * tests/012/seq.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New functions: subq, subql, subqual and subst.Kaz Kylheku2021-12-221-0/+4
| | | | | | | | | | | | | | | * eval.c (eval_init): Register new intrinsics. * lib.c, lib.h (subq, subql, subqual, subst): New functions. * tests/012/seq.tl: New test cases. * stdlib/optimize.tl (subst): Function removed. The new subst drop-in replaces this one. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* rot, nrot: new functions.Kaz Kylheku2021-12-071-0/+2
| | | | | | | | | | | | | | * eval.c (eval_init): nrot, rot intrinsics registered. * lib.c (nrot, rot): New functions. * lib.h (nrot, rot): Declared. * tests/012/seq.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* tuples*: new function.Kaz Kylheku2021-12-041-0/+1
| | | | | | | | | | | | | | | * eval.c (eval_init): Register tuples* intrinsic. * lib.c (tuples_star_func): New static function. (tuples_star): New function. * lib.h (tuples_star): Declared. * tests/012/seq.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: replace-env.Kaz Kylheku2021-09-251-0/+1
| | | | | | | | | | | | | | | | | | | Using this new function together with env, it's now possible to save the set of environment variables, clobber it to a specified set (possibly empty) and then restore it. Useful for improved security in running child processes. * lib.[ch] (chk_substrdup_utf8): New function. * sysif.c (replace_env): New function. (sysif_init): Register replace-env intrinsic. * sysif.h (replace_env): Declared. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* gcc11: warnings related to struct args allocation..Kaz Kylheku2021-09-081-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As reported by Paul A. Patience, GCC 11 warns about situations in a few places where we do args_decl(args, 0) to allocate an absolutely empty argument list object. (This by the way, is only done in places where we are absolutely sure that the function we call will not be accessing the arguments. The usual rule is that there have to be at least ARGS_MIN arguments allocated, currently 4, and code relies on that being the case! So the places which call args_decl(args, 0) are coded carefully, checking that args is not passed anywhere where ARGS_MIN space is required.) Anyway, in the 0 case, the val arg[1] member of struct args is not allocated at all, because we call alloca(offsetof (struct args, arg)). Now GCC 11 notices this and complains that accesses to the other members like args->fill or args->list are using a struct that has not been entirely allocated. This, even though those members lie entirely within the allocated area. The fix for this is two faceted. Firstly, on C99, this diagnostic goes away if we make one simple change: declare the arg array as a flexible array member: val arg[]. However, we still support C90 in maintainer mode. So in maintainer mode, we stick with the 1. But we ensure that the places which call args_decl(args, 0) will pass 1 instead of 0, so the whole structure is allocated. * lib.h (FLEX_ARRAY): New macro: empty definition in C99 or later, otherwise 1. * args.h (struct args): Declare the size of the arg member using the new FLEX_ARRAY macro from lib.h. (ARGS_ABS_MIN): New macro, the absolute args minimum: zero in C99 mode, 1 in maintainer C90 mode. * ffi.c (ffi_struct_in, ffi_struct_get, make_zstruct): Use ARGS_ABS_MIN instead of 0 when preparing dummy args for make_struct call. * struct.c (struct_from_plist, struct_from_args, make_struct_lit): Use ARGS_ABS_MIN instead of zero when preparing dummy args for make_struct_impl or make_struct call.
* exceptions: hack to store errno in string object.Kaz Kylheku2021-09-071-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Basic idea: when we throw an exception that pertains to a system error which has an errno code, we can stick the errno into the memory area of the character string, into the wchar_t that immediately follows the null terminator. We can do this because strings track their actual allocation size. A pair of setter/getter functions to set and retrieve this value are provided, and all functions in the code which can set such a code are updated to do so, simply by calling the newly added uw_ethrowf that drop-in replaces for uw_throwf. * lib.[ch] (string_set_code, string_get_code): New functions. * unwind.[ch] (uw_ethrowf): New function. * eval.c (eval_init): Register string-set-code and string-get-code intrinsics. * ftw.c (ftw_wrap): Switch to uw_ethrowf. * parser.c (open_txr_file): Likewise. * socket.c (dgram_overflow): Store the ENOBUFS error in errno, and use uw_ethrowf instead uw_throwf. (dgram_get_byte_callback, dgram_flush, sock_bind, to_connect, open_sockfd, sock_connect, sock_listen, sock_accept, sock_shutdown, sock_timeout, socketpair_wrap): Switch to uw_ethrowf. * stream.c (dev_null_get_fd, stdio_maybe_read_error, stdio_maybe_error, stdio_close, pipe_close, open_directory, open_file, open_fileno, open_tail, fds_subst, open_subprocess, open_command, remove_path, rename_path, tmpfile_wrap, mkdtemp_wrap, mkstemp_wrap): Switch to uw_ethrowf. * sysif.c (mkdir_wrap, ensure_dir, chdir_wrap, getcwd_wrap, rmdir_wrap, mknod_wrap, mkfifo_wrap, chmod_wrap, do_chown, symlink_wrap, link_wrap, readlink_wrap, close_wrap, val exec_wrap, stat_impl, do_utimes, pipe_wrap, poll_wrap, getgroups_wrap, setuid_wrap, seteuid_wrap, setgid_wrap, setegid_wrap, setgroups_wrap, getresuid_wrap, setresuid_wrap, setresgid_wrap, crypt_wrap, uname_wrap, opendir_wrap, getrlimit_wrap, setrlimit_wrap): Likewise. * termios.c (tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap, tcdrain_wrap, tcflush_wrap, tcflow_wrap): Likewise. * tests/018/errno.tl: New file. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* string-finish: new function.Kaz Kylheku2021-09-071-0/+1
| | | | | | | | | | | | * eval.c (eval_init): Register string-finish intrinsic. * lib.c (string_finish): New function. * lib.h (string_finish): Declared. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.