summaryrefslogtreecommitdiffstats
path: root/lib.c
Commit message (Collapse)AuthorAgeFilesLines
* Print ([...] . @var) and ([...] . @(expr)) notation.Kaz Kylheku2022-05-111-2/+11
| | | | | | | | | | | This change fixes objects like (@a @b . @c) being printed as (@a @b sys:var c). This is piggybacked into the logic which renders dotted unquotes. In other words, we are already printing (x . ,y) in that from rather than (x sys:unquote y); we just recognize sys:var, and sys:expr in the same code. * lib.c (obj_print_impl): Recognize dotted metavariables and metaexpressions similarly to dotted unquotes.
* New function: isecp.Kaz Kylheku2022-03-301-0/+32
| | | | | | | | | | | | | | | | | * 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/+57
| | | | | | | | | | | | | | | | * 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.
* find-max: convert to seq_info iteration.Kaz Kylheku2022-02-221-64/+17
| | | | | | | | | | | | * lib.c (find_max): Simplify into a single loop rather than handling various sequence types specially. This means it works for all iterable objects now. * txr.1: find-max documentation updated; discussion of hash tables removed, since the described behavior is the one expected for hash tables as iterables. * tests/012/seq.tl: Add some test coverage.
* New functions: find-max-key and find-min-key.Kaz Kylheku2022-02-211-0/+30
| | | | | | | | | | | | | * 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.
* ffi: move socket stuff to socket module.Kaz Kylheku2022-02-171-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * alloca.h (zalloca): Macro moved here from ffi.c; it's useful to any code that wants to do a zero-filled alloca, and socket.c needs it now. * ffi.c (HAVE_SOCKETS): All includes conditional on HAVE_SOCKETS removed. (zalloca): Macro removed; moved to alloca.h. (ffi_type_struct_checked, ffi_type_lookup): Static functions changed to external linkage. (ffi_type_size, ffi_type_put, ffi_type_get): New functions, used by external module that has incomplete definition of struct txr_ffi_type. (type_by_size): New static array, moved out of ffi_init_extra_types function. (ffi_type_by_size): New function. (ffi_init_extra_types): type_by_size array relocated to file scope. (sock_opt, sock_set_opt): Moved to socket.c, and adjusted to use newly developed external access to needed ffi mechanisms. (ffi_init): Numerous definitions related to sockets removed; these go to socket.c. * ffi.h (struct txr_ffi_type): Declared here now as incomplete type. (ffi_type_struct_checked, ffi_type_size, ffi_type_put, ffi_type_get, ffi_type_lookup, ffi_type_by_size): Declared. * lib.c (init): Call new function sock_init. * socket.c (sock_opt, sock_set_opt): New functions, moved from ffi.c, and slightly adapted to work with external interfaces exposed by ffi.c. (sock_init): New function. This performs unconditional initializations not keyed to the lazy loading lisplib.c mechanism. Here we create the socklen-t FFI type. FFI types lookup doesn't trigger lazy loading, so we do it this way; the alternative would be to introduce lazy load triggering to FFI type lookup, just for this one type. (sock_load_init): All the socket function and variable registrations move here from ffi_init.
* all: wrong self name.Kaz Kylheku2022-02-131-1/+1
| | | | * lib.c (all_satisfy): self should be "all" rather than "some".
* lib: fix return value of separate for nil seq.Paul A. Patience2022-02-071-1/+1
| | | | | * lib.c (separate): Return (list nil nil) instead of just nil when the sequence parameter is nil, as is documented.
* Use null_string throughout code base.Kaz Kylheku2022-02-051-1/+1
| | | | | | | | | | | | | | | | * eval.c (load): Use null_string instead of lit(""). * lib.c (obj_init): Likewise. * match.c (LOG_MATCH, LOG_MISMATCH, do_txeval): Likewise. * parser.c (regex_parse, lisp_parse_impl, find_matching_syms): Likewise. * stream.c (do_parse_mode): Likewise. * txr.c (sysroot_init): Likewise. (txr_main): Replace string(L"") with null_string.
* New function: copy-cptr.Kaz Kylheku2022-01-281-0/+8
| | | | | | | | | | | | | | | * 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-108/+1
| | | | | | | | | | | | | | | | | | | | | | | * 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/+10
| | | | | | | | | | | | | | * 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.
* cptr-int: allow full unsigned range.Kaz Kylheku2022-01-131-1/+4
| | | | | | | | | | | | | | The cptr-int function requries an address to be expressed as a signed integer, which is incovenient. E.g. -2147483648 to 2147483647 in a 32 bit address space. Let's fix it to accept an extended range. * lib.c (cptr_int): Convert the argument value to a ucnum if it is positive according to plusp, otherwise to cnum. Then either one to the mem_t * pointer. Thus we can accept either signed or unsigned values. * txr.1: Document the extended range of cptr-int.
* 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.
* Casts have crept into the code not wrapped by macros.Kaz Kylheku2022-01-061-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is against TXR coding conventions to use the C cast notation. The usage creeps into the code. To find instances of this, we must compile using GNU g++, and add -Wold-style-cast via EXTRA_FLAGS. * eval.c (prof_call): Use macro instead of cast. * ffi.c (pad_retval, ffi_varray_alloc, make_ffi_type_union, carray_dup, carray_replace, uint_carray, int_carray, put_carray, fill_carray): Likewise. * itypes.c (c_i64, c_u64): Likewise. * lib.c (cyr, chk_xalloc, spilt_str_keep, vector, cobj_register): Likewise. * linenoise.c (record_undo): Likewise. Also, drop one superfluous cast: wstrdup_fn returns wchar_t *. (flash, edit_insert, edit_insert_str): Use macro instead of cast. * mpi/mpi.c (s_mp_ispow2d): Likewise. * parser.c (lino_getch): Likewise. * rand.c (make_random_state, random_buf): Likewise. * stream.c (generic_get_line, do_parse_mode): Likewise. * struct.c (get_duplicate_supers, call_initfun_chain, call_postinitfun_chain): Likewise. * sysif.c (c_time): Likewise. * tree.c (tr_insert): Likewise.
* lazy-str-get-trailing-list: spurious empty string issue.Kaz Kylheku2022-01-041-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (lazy_str_get_trailing_list): Remove the spurious empty string caused by splitting on the terminator. Whenever the materialized prefix is not-empty, and there is a non-empty terminator, the prefix necessarily ends in the termintator. If we split on the terminator, the list of pieces ends in in an empty string, which is undesirable. This has to be subject to compat, unfortunately; it's a very visible behavior that affects the continuation of line-based matching after the @(freeform) directive. * tests/006/freeform-5.txr: With this fix, we no longer have to match the spurious blank line coming from @(freeform). * tests/015/lazy-str.tl: New file. * txr.1: Updated documentation with compat notes. There was some outright incorrect text describing lazy-str-get-trailing-list. Also, the lazy-str-force-upto and lazy-str-force were under-documented. The return value of the former was not completely described: that it returns t in the other case when not returning nil. It wasn't mentioned that the functions observe the limit-count. Moreover, the exact algorithm for forcing is now documented.
* Eliminate declaration-after-statement everywhere.Kaz Kylheku2021-12-291-35/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The use of -ansi doesn't by itself diagnose instances of some constructs we don't want in the project, like mixed declarations and statements. * configure (diag_flags): Add -Werror=declaration-after-statement. This is C only, so filter it out for C++. Also add -Werror=vla. * HACKING: Update inaccurate statements about what dialect we are using. TXR isn't pure C90: some GCC extensions are used. We even use long long if the configure script detects it as working, and some C99 library features. * buf.c (replace_buf, buf_list): Fix by reordering. * eval.c (op_dohash, op_load_time_lit): Fix by reordering. * ffi.c (ffi_simple_release): Fix by reordering. (align_sw_get): Fix empty macro to expand to dummy declaration so a semicolon after it isn't interpreted as a statement. On platforms with alignment, remove a semicolon from the macro so that it requires one. (ffi_i8_put, ffi_u8_put): Fix by reordering. * gc.c (gc_init): Fix with extra braces. * hash.c (hash_init): Fix by reordering. * lib.c (list_collect_revappend, sub_iter, replace_str, replace_vec, mapcar_listout, mappend, mapdo, window_map_list, subst): Fix by reordering. (gensym, find, rfind, pos, rpos, in, search_common): Fix by renaming optional argument and using declaration instead of assignment. * linenoise/linenoise.c (edit_in_editor): Fix by reordering. * parser.c (is_balanced_line): Fix by reordering. * regex.c (nfa_count_one, print_rec): Fix by reordering. * signal.c (sig_mask): Fix by reordering. * stream.c (get_string): Fix by renaming optional argument and using declaration instead of assignment. * struct.c (lookup_static_slot_desc): Fix by turning mutated variable into block local. (umethod_args_fun): Fix by reordering. (get_special_slot): Fix by new scope via braces. * sysif.c (usleep_wrap): Fix by new scope via braces. (setrlimit_wrap): Fix by new scope via braces. * time.c (time_string_meth, time_parse_meth): Fix by reordering. * tree.c (tr_do_delete_spec): Fix by new scope via braces. * unwind.h (uw_block_beg): New macro which doesn't define RESULTVAR but expects it to refers to an existing one. (uw_block_begin): Replace do while (0) with enum trick so that we have a declaration that requires a semicolon, rather than a statement, allowing declarations to follow. (uw_match_env_begin): Now opens a scope and features the same enum trick as in uw_block_begin. This fixes a declaration-follows-statement issue in the v_output function in match.c. (uw_match_env_end): Closes scope opened by uw_match_env_begin. * unwind.c (revive_cont): Fix by introducing variable, and using new uw_block_beg macro. * vm.c (vm_execute_closure): Fix using combination of local variable and reordering.
* The pairlis function comes to TXR Lisp.Kaz Kylheku2021-12-221-0/+19
| | | | | | | | | | | | * 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/+33
| | | | | | | | | | | | | | | * 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.
* less: bug, vectors not supported.Kaz Kylheku2021-12-201-1/+2
| | | | | | | | * lib.c (less_tab_init): Add missing initialization for VEC, with a priority above CONS: all vectors are greater than conses. The BUF priority is bumped to 7. * test/012/less.tl: New file.
* tree: support for duplicate keys.Kaz Kylheku2021-12-171-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * tree.c (tr_insert): New argument for allowing duplicate. If it is true, suppresses the case of replacing a node, causing the logic to fall through to traversing right, so the duplicate key effectively looks like it is greater than the existing duplicates, and gets inserted as the rightmost duplicate. (tr_do_delete_specific, tr_delete_specific): New static functions. (tree_insert_node): New parameter, passed to tr_insert. (tree_insert): New parameter, passed to tree_insert_node. (tree_delete_specific_node): New function. (tree): New parameter to allow duplicate keys in the elements sequence. (tree_construct): Pass t to tree to allow duplicate elements. (tree_init): Update registrations of tree, tree-insert and tree-insert-node. Register tree-delete-specific-node function. * tree.h (tree, tree_insert_node, tree_insert): Declarations updated. (tree_delete_specific_node): Declared. * lib.c (seq): Pass t argument to tree_insert, allowing duplicates. * parser.c (circ_backpatch): Likewise. * parser.y (tree): Pass t to new argument of tree, so duplicates are preserved in the element list of the #T literal. * y.tab.c.shipped: Updated. * tests/010/tree.tl: Test cases for duplicate keys. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* tree-count: new function.Kaz Kylheku2021-12-171-0/+2
| | | | | | | | | | | | | * tree.c (tree_count): New function. (tree_init): tree-count intrinsic registered. * tree.h (tree_count): Declared. * lib.c (length): Support search tree argument via tree_count. * tests/010/tree.tl: Test cases for tree-count, indirectly via len. * txr.1: Documented.
* iter-reset: gc problem.Kaz Kylheku2021-12-171-0/+3
| | | | | | | | | | | | | * lib.c (iter_reset): When we reinitialize the iterator, it can allocate a new secondary object, e.g. using hash_begin, which is stored into the iterator. This is potentially a wrong-way assignment in terms of GC generations and so we must call mut(iter) to indicate that the object has been suspiciously mutated. We only do this if the iterator has a mark function. If it doesn't have one, then it isn't wrapping a heap object, and so doesn't have this issue. (seq_reset): This has the same issue, and the fix is the same. Since ths function is obsolescent, we don't bother doing the si->ops->mark check; we optimize for code size instead.
* iter-begin: gc problem.Kaz Kylheku2021-12-171-4/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Issue 1: the seq_iter_init_with_info function potentially allocates an object via hash_begin or tree_begin and installs it into the iterator. The problem is that under iter_begin, the iterator is a heaped object; this extra allocation can trigger gc which pushes the iterator into the mature generation; yet the assignment in seq_iter_init_with_info is just a plain assignment without using the set macro. Issue 2: when gc is triggered in the above situations, it crashes due to the struct seq_iter being incompletely initialized. The mark function tries to dereference the si->ops pointer. Alas, this is initialized in the wrong order inside seq_iter_init_with_info. Concretely, tree_begin is called first, and then the it->ops = &si_tree_ops assignment is performed, which means that if the garbage collector runs under tree_begin, it sees a null it->ops pointer. However, this issue cannot just be fixed here by rearranging the code because that leaves Issue 1 unsolved. Also, this initialization order is not an issue for stack-allocated struct seq_iters. The fix for Issue 1 and Issue 2 is to reorder things in iter_begin. Initialize the iterator structure first, and then create the iterator cobj. Now, of course, that goes against the usual correct protocol for object initialization. If we just do this re-ordering naively, we have Issue 3: the familiar problem that the cobj() call triggers gc, and the iterator object (e.g. from tree_iter) that has been stored into the seq_iter structure is not visible ot the GC, and is reclaimed. * lib.c (iter_begin): reorder the calls so that seq_iter_init_with_info is called first, and then the cobj to create from it the heap-allocated iterator, taking care of Issue 1 and Issue 2. To avoid Issue 3, after initializing the structure, we pull out the vulnerable iterator object into a local variable, and pass it to gc_hint(), to ensure that the variable is spilled into the stack, thereby protecting it from reclamation. (seq_begin): This function has exactly the same issue, fixed in the same way.
* rot, nrot: new functions.Kaz Kylheku2021-12-071-0/+42
| | | | | | | | | | | | | | * 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/+54
| | | | | | | | | | | | | | | * 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.
* tuples: change to abstract iteration.Kaz Kylheku2021-12-021-10/+16
| | | | | | | | | | | | | | | * lib.c (make_like): In the COBJ case, recognize an iterator object. Pull out the underlying object and recurse on it. This is needed in tuples_func, where make_like will now be called on the abstract iterator, rather than the actual sequence object. (tuples_func): The incoming object is now an iterator, and not a sequence; we need to handle it with iter_more, iter_item and iter_step. (tuples): Instead of nullify, begin iteration with iter_begin, and use iter_more to test for empty. In non-empty case, put propagate the iterator thorugh the lazy cons car field, rather than the sequence.
* tuples: check length argument.Kaz Kylheku2021-12-021-0/+4
| | | | | | | * lib.c (tuples): Check that n argument giving tuple size is a is a positive integer. * tests/012/seql.tl: Test case added.
* less: symbolic arguments: fix crash and incorrectness.Kaz Kylheku2021-11-011-4/+3
| | | | | | | | | | | * lib.c (less): We cannot direclty access right->s.package because the right operand can be nil. This causes a crash. Furthermore, the separate NIL case is wrong. If the left object is nil, the same logic must be carried out as for SYM. The opposite operand might have the same name, and so packages have to be compared. We simply merge the two cases, and make sure we use the proper accessors symbol_name and symbol_package to avoid blowing up on nil.
* printer: bug: fallback syms printed without prefix.Kaz Kylheku2021-10-121-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | This is a basic read/print consistency problem. When a symbol is printed that is anywhere in the fallback list of the current package, we are dumping it unqualified, even if it is hidden by a same-named symbol in the current package itself or such a symbol occurring earlier in the fallback list. * lib.c (symbol_needs_prefix): When the to-be-printed symbol is found in the fallback list, re-scan the current package for a symbol having the same name, as well as the preceding nodes in the fallback list. If such a symbol is found, then the to-be printed symbol must be package-qualified. * tests/012/syms.expected: New file. * tests/012/syms.tl: Likewise. * tests/012/compile.tl: Pull syms into compile job. * txr.1: Clarify text about this. The existing text's only reasonable interpretation supports the behavior which this patch ensures (which is needed on grounds of read/print consistency) but the text lacks precision.
* New function: replace-env.Kaz Kylheku2021-09-251-0/+15
| | | | | | | | | | | | | | | | | | | 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.
* lib: fix self name of cmp-str.Paul A. Patience2021-09-171-3/+3
| | | | * lib.c (cmp_str): Fix self name and use it in uw_throwf call.
* seq_iter: gc crash marking vector iterator.Kaz Kylheku2021-09-131-4/+4
| | | | | | | | | * lib.c (si_vec_ops): This must be initialized with seq_iter_ops_init_nomark, since it uses a cnum index, and not a val iter; the seq_iter_mark_op will pass the cnum bit pattern to gc_mark an cause a crash. (si_null_ops): While we are at it, this should also use seq_iter_ops_init_nomark, because it->ui.iter is always nil.
* exceptions: hack to store errno in string object.Kaz Kylheku2021-09-071-0/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-extend: use num, not num_fast.Kaz Kylheku2021-09-071-3/+3
| | | | | | | | * lib.c (string_extend, string_finish): When we update the alloc value in the string, we should be using num, because the cnum value is not necessarily in the fixnum range. That's the whole reason we are using the set macro: because the assigned value could be a heap-allocated bignum. Which it will never be, if we use num_fast.
* string-finish: new function.Kaz Kylheku2021-09-071-0/+19
| | | | | | | | | | | | * 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-16/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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/+22
| | | | | | | | | | | | * 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: allow mixed fixnum/bignum ranges.Kaz Kylheku2021-08-291-6/+18
| | | | | | * lib.c (seq_iter_init_with_info): The to value in a range could be a bignum, which we should treat as a bignum range, rather than blowing up due to calling c_num on that value.
* seq_iter: fix gc issues.Kaz Kylheku2021-08-291-25/+22
| | | | | | | | | | | | | | | | | | | | * 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-39/+79
| | | | | | | | | | | | | | | | | | | | | 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.
* sub: allow generic iterables.Kaz Kylheku2021-08-221-4/+51
| | | | | | | | | | | | | | | | In this patch we allow the s in (sub s from to) and [s from..to] to be any iterable. * lib.c (iter_dynamic, sub_iter): New static function. (generic_funcall): Handle all objects via the sequence case: ref, sub and all that. Unfortunately, we lose some error handling at the level of the sub function. But we allow any iterable to be passed through to sub. (sub): Handle default case through sub_iter. * tests/012/iter.tl: New cases. * txr.1: Documented.
* iter-begin: allow iterator argument.Kaz Kylheku2021-08-221-0/+5
| | | | | | | | * lib.c (seq_iter_init_with_info): Allow the iterated object to be an iterator, in which case a copy of the iterator is set up. * txr.1: Documented.
* sub-list: better handling of from value of t.Kaz Kylheku2021-08-221-4/+2
| | | | | | | | * lib.c (sub_list): If from is t, then just return nil. Do not reset it to nil in this case. After this we know from is not nil; we don't have to check for this inside one loop. That loop was wastefully iterating over the list in the from == nil case only to calculate nil.
* iter-begin: string range support.Kaz Kylheku2021-08-221-2/+84
| | | | | | | | | | | | | | Ranges like "AAA".."ZZZ" are now possible. * lib.c (seq_iter_get_range_str, seq_iter_peek_range_str, seq_iter_get_rev_range_str): New static functions. (seq_iter_init_with_info): Support string ranges via above new functions. Range direction test is now done with less and equal rather than lt and gt. * tests/012/iter.tl: New file. * txr.1: Documented.
* 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.
* int-str: 0x bug.Kaz Kylheku2021-08-131-7/+8
| | | | | | | | | | | | | | | * lib.c (int_str): The problem here is that we are recognizing and skipping the 0x prefix for all bases. So for instance (int-str "0x123") produces 123. The correct requirement, and the intent of the code, is that the C conventions are only honored if the base is specified as the character #\c. In any other base, including omitted base defaulting to 10, a leading zero is just a leading zero, and 0x is a zero followed by the junk character x. Therefore, if we have any valid base that isn't #\c, and 0x has been seen, we must return zero. We must not do this only in the base 16 case. * tests/016/conv.tl: New file.
* lazy-stream-cons: control close throwing behavior.Kaz Kylheku2021-08-071-7/+37
| | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* gc: problem in several object copying functions.Kaz Kylheku2021-07-291-10/+3
| | | | | | | | | | | | | | | | | | The functions copy-cons, copy-tree, copy-fun and copy-tnode have a problem. They copy the original object bitwise with a structure assignment, and then make some adjustments. The problem is that this inappropriately copies the object's metadata related to gc, such as its generation number or finalization count. To fix this, we introduce a copy_obj function, which is a companion to make_obj. This performs a shallow copy of an object without incorrectly propagating inappropriate metadata. * gc.c, gc.h (copy_obj): New function. * lib.c (copy_fun, copy_cons, copy_tree): Use copy_obj, instead of make_obj plus structure assignment. * tree.c (copy_tnode): Likewise.
* subtypep: handle struct type objects.Kaz Kylheku2021-07-271-4/+4
| | | | | | | | | | | | | The subtypep function has poor requirements, handling only type symbols. Let's extend it to handle structure type objects. * lib.c (subtypep): In all cases when an argument is considered to be a possible structure symbol, and thus subject to find_struct_type, consider whether it already is a struct type, and just take it as-is. * tests/012/type.tl: New tests. * txr.1: Updated.