summaryrefslogtreecommitdiffstats
path: root/lib.h
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* string-extend: third optional argument.Kaz Kylheku2021-09-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A Boolean optional argument to string-extend indicates whether this is likely the last call to string-extend, so memory can be trimmed accordingly. * eval.c (eval_init): Update string-extend registration. * filter.c (trie_filter_string): Pass nil for new argument of string_extend. * lib.c (str_seq, replace_str, lazy_str_force, lazy_str_force_upto): Pass nil for new argument of string_extend. (rem_impl, remove_if, separate): Pass t for new argument of string_extend on last iteration, nil otherwise. (string_extend): Implement new third argument, defaulted to nil. Switch from chk_grow_vec to the more specific chk_wrealloc, which simplifies the code. * lib.h (string_extend): Declaration updated. * parser.y (litchars): Pass t as last argument of string_extend since we know syntactically that these reductions finalize the string. (restlitchar): Pass nil as the last argument of string_extend, since we know syntactically that it isn't the last. * regex.c (scan_until_common): Pass nil for new argument of string_extend. * txr.1: Documented.
* New function: delcons.Kaz Kylheku2021-09-021-0/+1
| | | | | | | | | | | | * eval.c (eval_init): Register delcons intrinsic. * lib.[ch] (delcons): New function. * tests/010/cons.tl: New file. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* seq_iter: fix gc issues.Kaz Kylheku2021-08-291-1/+3
| | | | | | | | | | | | | | | | | | | | * lib.h (struct seq_iter_ops): New operation, mark. (seq_iter_ops_init): Default the mark operation to seq_iter_mark_op. (seq_iter_ops_init_nomark): New macro. * lib.c (seq_iter_mark_op): New static function. (si_range_cnum_ops, si_range_chr_ops, si_rev_range_cnum_ops, si_rev_range_chr_ops, si_chr_ops): Initialize with seq_iter_ops_init_nomark so that the iterator has no mark operation. All other iterator types have the above new static function as their mark op. (seq_iter_mark): Simplified: if the iterator has a mark op, call it. (seq_next, iter_step): If the iterator has a mark op, that means that the seq_get operation is likely replacing one heap object with another, and so mut(iter) must be called to inform the garbage collector of the assignment.
* seq_iter: refactoring.Kaz Kylheku2021-08-291-3/+9
| | | | | | | | | | | | | | | | | | | | | This is needed in preparation for fixing some gc bugs in iteration in a less hacky way. * lib.h (struct seq_iter): Members get and peek removed, replaced by ops pointer. (struct seq_iter_ops): New struct type. (seq_get, seq_peek): Call get and peek through ops table. * lib.c (seq_geti): Refer to get through ops. (si_null_ops, si_list_ops, si_vec_ops, si_hash_ops, si_tree_ops, si_range_cnum_ops, si_range_chr_ops, si_range_bignum_ops, si_range_str_ops, si_rev_range_cnum_ops, si_rev_range_chr_ops, si_rev_range_bignum_ops, si_rev_range_str_ops, si_chr_ops, si_num_ops, si_oop_ops, si_fast_oop_ops): New static structures. (seq_iter_init_with_info): Point new ops member of seq_iter to one of the new structures. Remove initializations of get and peek.
* license: reformat to fit 80 columns.Kaz Kylheku2021-08-161-12/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Makefile, alloca.h, args.c, args.h, arith.c, arith.h, buf.c, buf.h, chksum.c, chksum.h, chksums/crc32.c, chksums/crc32.h, combi.c, combi.h, 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, rand.c, rand.h, regex.c, regex.h, signal.c, signal.h, socket.c, socket.h, stdlib/asm.tl, stdlib/awk.tl, stdlib/build.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.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h, vm.c, vm.h, vmop.h: License reformatted. * lex.yy.c.shipped, y.tab.c.shipped, y.tab.h.shipped: Updated.
* lazy-stream-cons: control close throwing behavior.Kaz Kylheku2021-08-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Update registrations of lazy-stream-cons and get-lines with one more optional argument. * lib.c (simple_lazy_stream_func_nt, lazy_stream_func_nt): New static functions. (lazy_stream_cons): Take a new argument, no_throw_close, defaulting it to nil. When calling close_stream directly, pass the inverted value of no_throw_close. Choose the new _nt functions for the lazy list if no_throw_close is true; those functions pass nil as the second argument of close_stream. * lib.h (lazy_stream_cons): Declaration updated. * match.c (v_next_impl, open_data_source, match_fun): Pass down the nothrow value to lazy_stream_cons, or else nil in situations when that is not applicable or there is no such value. Thus the :nothrow feature of v_next will now not only ensure that there is no exception when opening the stream but also when closing it. Unusual situations encountered when the lazy list reads from the stream still throw. * txr.1: Documented.
* struct: get rid of pointer typedef.Kaz Kylheku2021-07-271-2/+2
| | | | | | | | * lib.h (slot_cache_t): Typedef removed. (struct sym): Use slot_cache_set_t *. * struct.c (struct_type_finalize, lookup_slot, lookup_static_slot, lookup_static_slot_desc): Likewise.
* lib: default_arg_strict becomes macro.Kaz Kylheku2021-07-141-4/+1
| | | | | | | | | | | * lib.h (default_arg_strict): Inline function converted to macro, so that we can suppress the evaluation of the default expression if it is not required. The default_arg_strict idiom is being used all over the stream library now. The common default value expressions like std_out are macros that access the dynamic variable by symbol. We don't want to be wastefully doing that on each stream operation, whether or not a stream argument has been supplied.
* New functions: trim-short-suffix, trim-long-suffix.Kaz Kylheku2021-07-101-0/+1
| | | | | | | | | | | | | | | * lib.c, lib.h (chk_substrdup): New function. * stream.c, stream.h (trim_short_suffix, trim_long_suffix): New functions. (stream_init): trim-short-suffix and trim-long-suffix intrinsics registered. * tests/018/path.tl: New tests. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* lib: new function separate.Paul A. Patience2021-07-091-0/+1
| | | | | | | | | | | | * lib.c (separate): New function. * lib.h (separate): Declared. * eval.c (eval_init): Register separate intrinsic. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* defstruct: diagnose built-in type being redefined.Kaz Kylheku2021-07-091-2/+1
| | | | | | | | | | | | | | | | | | * eval.c (eval_init): Register built-in-type-p intrinsic. * lib.c (buitin_type_p): Rename to built_in_type_p since the word built-in is hyphenated. The function also tests whether the argument is a COBJ class. (cobj_class_exists): Function removed. * stdlib/doc-syms.tl: Updated. * stdlib/struct.tl (defstruct): Add built-in-type-p check. * struct.c (make_struct_type): Call only built_in_type_p; cobj_class_exists is gone. * txr.1: Document built-in-type-p.