summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* keep-keys-if: rework with generic sequence processing.Kaz Kylheku2024-02-261-56/+12
| | | | | * lib.c (keep_keys_if): Replace with generic sequence iteration and building.
* New sequence building framework.Kaz Kylheku2024-02-262-123/+231
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Just as the "seq_iter" iterators help to condense the code for iterating any kind of sequence, "seq_builder" objects solve the problem of producing a sequence of the same kind as an input sequence. Until now, two approaches have been taken for this. One was to have separately coded cases: code iterating over a string building up a string, and so on. The other has been to produce a list, which is then coerced to the right sequence type using make_like. The approach introduced here is similar to using make_like, but without wastefully consing up a temporary list. The remove-if, remqual, remql, remq and keep-if functions are retargetted to this new abstraction. * lib.h (struct seq_build, seq_build_t): New struct type. (struct seq_build_ops): New struct type. (seq_build_ops_init): New macro. (seq_build_init, seq_add, seq_pend, seq_finish): Functions declared. * lib.c (seq_build_generic_pend, seq_build_obj_mark, seq_build_struct_mark, seq_build_carray_mark, seq_build_vec_add, seq_build_str_add, seq_build_buf_add, seq_build_buf_pend, seq_build_buf_finish, seq_build_list_add, seq_build_list_finish, seq_build_struct_finish, seq_build_carray_finish): New static functions. (sb_vec_ops, sb_str_ops, sb_buf_ops, sb_struct_ops, sb_carray_ops, sb_list_ops): New static structs. (seq_build_init, seq_add, seq_pend, seq_finish): New functions. (rem_impl, rem_if_impl): Reworked in terms of seq_iter and seq_build, becoming much shorter, and handling all iterable objects.
* keep-if: don't report as remove-if in errors.Kaz Kylheku2024-02-261-3/+7
| | | | | | | * lib.c (rem_if_impl): New static function, based on renaming remove_if, and adding a self parameter. (remove_if): Now wrapper around rem_if_impl. (keep_if): Retarget to rem_if_impl, passing "keep-if" name.
* doc: add rationale about let vs let*.Kaz Kylheku2024-02-221-0/+22
| | | | | | * txr.1: Add Rationale: section to let and let* clarifying that the decision to make let parallel is for compatibility with other dialects like ANSI CL and Elisp.
* quips: new Lisp entry.Kaz Kylheku2024-02-181-0/+1
| | | | * quips.tl (%quips%): New dad humor.
* doc: fixes under macroexpand-params.Kaz Kylheku2024-02-151-17/+17
| | | | | * txr.1: Fix typo: for -> form; add missing leading indentation in example.
* compiler: use cons-count.Kaz Kylheku2024-02-091-1/+1
| | | | | | * stdlib/compiler.tl (simplify-variadic-lambda): Use cons-count to find occurrences of the rest variable rather than flatten and count.
* New function: cons-count.Kaz Kylheku2024-02-095-0/+71
| | | | | | | | | | | | | * eval.c (eval_init): Register cons-count intrinsic. * lib.c (cons_count_rec): New static function. (cons_count): New function. * lib.h (cons_count): Declared. * tests/012/cons.tl: New tests. * txr.1: Documented.
* New function: cons-find.Kaz Kylheku2024-02-095-22/+83
| | | | | | | | | | | | | | | | | * eval.c (cons_find): Static function removed; a new one is implemented in lib.c. (eval_init): Register cons-find intrinsic. * lib.c (cons_find_rec): New static function. (cons_find): New function. * lib.h (cons_find): Declared. * tests/012/cons.tl: New file. * txr.1: Documented cons-find together with tree-find. Document that tree-find's test-fun argument is optional, defaulting to equal.
* compiler: take advantage of fixed @(end) match.Kaz Kylheku2024-02-081-2/+1
| | | | | | * stdlib/compiler.tl (simplify-variadic-lambda): Remove work-around where two patterns are combined with or, expressing it the way it wants to be.
* match: remove bad restriction from @(sme) and @(end).Kaz Kylheku2024-02-083-14/+17
| | | | | | | | | | | | | | | | | | | | | | | | The end pattern in @(sme) and @(end) does not have to be a list pattern, dotted or otherwise. It should support any pattern whatsoever for a single object, which should match the terminating atom. The documentation says that, though not very clearly; it is reworded also. * stdlib/match.tl (check-end): Remove this function, since the end pattern can be any pattern. (pat-len): Bugfix: we are using the meq function incorrectly. The object being compared against several alternatives must be the leftmost argument of meq. This bug prevents a pattern like @(evenp @x) to be correctly considered of length zero. (sme, end): Remove calls to check-end, and just refer to original end variable. * tests/011/patmatch.tl: New tests. * txr.1: clarify that the end pattern may be any pattern, which can match just the terminating atom or a possibly dotted suffix.
* compiler: inlined chain: simplify variadic lambdas.Kaz Kylheku2024-02-081-2/+15
| | | | | | | | | | | | | | | The opip syntax often generates lambdas that have a trailing parameter and use [sys:apply ...]. This is wasteful in the second and subsequent argument positions of a chain, because we know that only a single value is coming from the previous function. We can pattern match these lambdas and convert the trailing argument to a single fixed parameter. * stdlib/compiler.tl (simplify-variadic-lambda): New function. (inline-chain-rec): Try to simplify every function through simplify-variadic-lambda. The leftmost function is treated in inline-chain, so these are all second and subsequent functions.
* compiler: implement inlining for chain expressions.Kaz Kylheku2024-02-072-2/+40
| | | | | | | | | | | | | | | | | | | | The opip syntax and its variants transforms into chain expressions. Currently, we emit actual chain function calls, and so all the chain arguments that are lambda expressions have become closures. In this commit, an inlining optimization is introduced which turns some chain function calls into chained expressions. The lambdas are then immediately called, and so succumb to the lambda-eliminating optimization. * stdlib/compiler.tl (compiler comp-fun-form): Handle chain forms. At optimization level 6 or higher, if the form is eligible for the transform, perform it. (inline-chain-rec, can-inline-chain, inline-chain): New functions. * txr.1: Mention that *opt-level* 6 does this chain optimization.
* compiler: whitespace issue.Kaz Kylheku2024-02-071-1/+1
| | | | | * stdlib/compiler (lambda-apply-transform): Fix misleading indentation.
* doc: missing plural.Kaz Kylheku2024-02-041-1/+1
| | | | | * txr.1: Under Pattern-Matching Notation: subject-verb agreement.
* New function: hist-sort-by.Kaz Kylheku2024-02-025-3/+37
| | | | | | | | | | | | | * eval.c (eval_init): Register hist-sort-by intrinsic. * lib.c (hist_sort_by): New function. (hist_sort): Wrapper for hist_sort_by now. * lib.h (hist_sort_by): Declared. * tests/012/sort.tl: Tests. * txr.1: Documented.
* hash-eql: regression: always returns zero.Kaz Kylheku2024-02-012-1/+7
| | | | | | | | | | | * hash.c (hash_eql): Use hash_traversal_limit for the initial value of the limit rather than zero. Commit 84e9903c27ede099e2361e15b16a05c6aa4dc819 in October 2019 fixed eql_hash to actually make use of the limit, which broke the assumption that we could use zero. * tests/010/hash.tl: Add a few tests for hash-equal and hash-eql.
* quips: new bad pun.Kaz Kylheku2024-01-201-0/+1
| | | | * stdlib/quips.tl (%quips%): New entry.
* We need a length-< special method.Kaz Kylheku2024-01-197-5/+67
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Structure objects can be used to implement lazy structures such as sequences. It is undesirable to take the length of a lazy sequence because it forces all of its elements to exist. Moreover, if the sequence is infinite, it is impossible. There are situations in which it is only necessary to know whether the length is less than a certain bound, and for that we have the length-< function. That works on infinite sequence such as lazy lists, requiring them to be forced only so far as to determine the truth value of the test. We need objects that implement lazy sequences to work with this function. * struct.h (enum special_slot): New member length_lt_m. * lib.h (length_lt_s): Symbol variable declared. * struct.c (special_sym): New entry in this table, associating the length_lt_m enum with the length_lt_s symbol variable. * lib.c (length_lt_s): Symbol variable defined. (length_lt): Handle COBJ objects that are structures. we test whether they have a length-< method, or else length method. If they don't have either, we throw. We don't fall back on the default case for objects that don't have a length-< method, because the diagnostic won't be good if they don't have a length method either; the programmer will be informed that the length function couldn't find a length method, without mentioning that it was actually length-< that is being used. * eval.c (eval_init): Register length-< using the length_lt_s symbol variable rather than using intern. * txr.1: Documented. * tests/012/oop-seq.tl: New tests.
* mmap: bug: low length diagnosed as "zero-sized element type"Kaz Kylheku2024-01-181-1/+1
| | | | | | | * ffi.c (mmap_wrap): Make the diagnostic depend on the actual condition that it's wording is about. If the element type is nonzero, but the length is too low for the array to have any elements, that is not strictly an error; we can let that pass.
* doc: mmap: document source parameter.Kaz Kylheku2024-01-181-0/+34
| | | | | | * txr.1: The source argument of mmap is not adequately documented. It can be an integer descriptor, stream or filename string.
* Copyright year bump 2024.Kaz Kylheku2024-01-18138-140/+140
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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, lib.c, lib.h, linenoise/linenoise.c, linenoise/linenoise.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, 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/csort.tl, stdlib/debugger.tl, stdlib/defset.tl, stdlib/doloop.tl, stdlib/each-prod.tl, stdlib/error.tl, stdlib/except.tl, stdlib/expander-let.tl, stdlib/ffi.tl, stdlib/getopts.tl, stdlib/getput.tl, stdlib/glob.tl, stdlib/hash.tl, stdlib/ifa.tl, stdlib/keyparams.tl, stdlib/load-args.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 2024.
* lib: avoid realloc with zero size.Kaz Kylheku2024-01-161-3/+13
| | | | | | | | | | | | | I spotted in the N3096 draft of ISO C (April 2023) that a zero size in realloc is no longer defined behavior, like it used to be. I don't know exactly when it changed; in C99 it is not mentioned. We call realloc only in one place, so we can defend agains this. * lib.c (chk_realloc): If the new size is zero, we implement the C99 and older semantics: deallocate the object, and then behave like malloc(0). In other cases, we use realloc.
* ppc64/clang: save/restore vector register vr31.Kaz Kylheku2024-01-112-1/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes crashes in the test cases when TXR is built with clang on little-endian PPC64. Clang uses vector instructions, but our jmp.S does not save any vector registers. In some places this causes a problem. I've noticed much of the code just uses vrs0, vrs1 and vrs63 for doing small things, like initializing small structures with a single instruction. The functions that use more of these registers don't call anything that saves and restores a context. In this patch we just save/restore vrs63, which maps to vr31. The vrs0 and vrs1 don't have to be saved and restored; the setjmp function doesn't do it. Everything is conditional on __ALTIVEC__. * unwind.h (jmp): We add vr31 to the PPC64 version of struct jmp. The instructions which load and store this requires 32 byte alignment, so we assert that. Note that the alignment leaves 8 bytes of padding at the end of the structure since there are 23 other registers to save. * jmp.S (jmp_save, jmp_restore): We save and restore v31 first and then move the pointer past it by 32 bytes to do the rest of the registers exactly as before. In jmp_save, we save an extra copy of the r11 register into the padding so that it is initialized. We don't like to encourage padding in the stack because in light of our GC's conservative scan of the stack, it promotes spurious retention of objects.
* lib: review cobj calls for gc incorrectness and fix.Kaz Kylheku2024-01-064-2/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | I looked at all cobj calls to see if there is a potential problem, looking for situations whereby the cobj call could trigger a gc that would destroy Lisp objects that the new object either stores, or that its continued initialization depends on. * stream.c (make_strlist_input_stream): call cobj earlier, then fill in the structure. Use chk_calloc to allocate the structure so any Lisp objects in it look like nil until it is initialized. * struct.c (make_struct_impl, make_lazy_struct): Use gc_hint on the type argument, to pin down the st structure that we use in initializations after the cobj call. If the type object were to disappear, the st structure would become invalid. * tree.c (copy_search_tree, make_similar_tree): Use gc_hint on the tree argument to pin down the otr structure that we reference in initializations (copy_tree_iter): Use gc_hint on iter, for similar reasons. * vm.c (vm_copy_closure): Use gc_hint on oclosure, to pin down the environment we are copying from it.
* eval: potential gc problem in binding.Kaz Kylheku2024-01-061-1/+1
| | | | | | | | | | * eval.c (reparent_env): This function is used in bindings helper, when special variables are involved. It makes a new environment the parent of an existing one, just by assigning the pointer. This is wrong under generational GC if it makes a mature object point to a new object. We fix it with the set macro. I've not seen a crash because of this; I caught it by inspection.
* gc: bug in sub-str on lazy string argument.Kaz Kylheku2024-01-061-0/+1
| | | | | | | | | | | This showed up as an intermittent segfault on OpenBSD of the test case tests/006/freeform-5.txr, reproducible quite often, around 30% to 60%. This was with gcc 4.2.1. * lib.c (lazy_sub_str): We need a gc_hint here on the prefix hend in pfxcopy. The garbage collector is scavenging that object, not seeing that we planted it into a malloced structure.
* sysif: unused parameter warning on solaris.Kaz Kylheku2024-01-051-0/+1
| | | | | * sysif.c (link_wrap_common): Cast the follow_link argument to void in the #else case to suppress warning.
* tests: fix tests/007/except-4.txr for Solaris, BSD.Kaz Kylheku2024-01-052-5/+2
| | | | | | | | | | | | | | | | | * tests/007/except-4.txr: The portable way to get a shell command that exits with a signal is to execute kill -KILL $$. If we use a signal that the shell catch like SIGTERM or SIGINT, we get nonportable behaviors. Some shells seem to catch the signal and then raise it again so they terminate with that signal. Some shells terminate normally, but create an exit status by OR-ing 0x80 with the caught signal. Let's use kill -KILL here and drop the tests for BSD and Solaris. * tests/007/except-3.txr: Fix the kill command here also. While this test wasn't failing on those platforms, it succeeds vacuously, since the exception being ignored by :nothrow is not actually thrown.
* openbsd: more tests fixes.Kaz Kylheku2024-01-055-5/+5
| | | | | | | | | | | | | * tests/014/socket-basic.tl: Test for :openbsd also were we test for :bsd. * tests/014/glob-carray.tl: Likewise. * tests/017/glob-zarray.tl: Likewise. * tests/017/mmap.tl: Likewise. * tests/018/chmod.tl: Likewise.
* build: wrong build order of STDLIB_EARLY_TLOS.Kaz Kylheku2024-01-051-5/+2
| | | | | | | | | | | | | | | | | The STDLIB_EARLY_TLOS are not being built in the intended order for several reasons. Firstly, the list is built by filtering STDLIB_TLOS which are in an order pulled by the wildcard command. Secondly, the order-only rule isn't preserving the order among the early tlos, only ensuring that those members of STDLIB_TLOS which occur in STDLIB_EARLY_TLOS are built before the others. * Makefile (STDLIB_EARLY_PATS): Variable removed. (STDLIB_EARLY_TLOS): Specified directly rather than via filtering. (all): Don't depend on $(STDLIB_TLOS) but rather on $(STDLIB_EARLY_TLOS) and $(STDLIB_LATE_TLOS) in that order. ($(STDLIB_LATE_TLOS):): Ordering rule removed.
* tests: fix on OpenBSD.Paul A. Patience2024-01-054-5/+11
| | | | | | | | * tests/common.tl (os-symbol): Add :openbsd. * tests/007/except-4.txr: Skip. * tests/018/crypt.tl: Skip unsupported salts, i.e., without leading "$". * tests/018/gzip.tl: Add -f to gzip command to force compression even if it does not make the file smaller.
* sysif: fix build on OpenBSD.Paul A. Patience2024-01-041-0/+2
| | | | | | | OpenBSD is missing RLIMIT_AS. * sysif.c (sysif_init): Register rlimit-as variable only if RLIMIT_AS is defined.
* doc: formatting under compiler-let.Kaz Kylheku2024-01-041-1/+1
| | | | * txr.1: Fix markup of syntax, invalid due to missing space.
* doc: clarification regarding sort stability.Kaz Kylheku2024-01-031-1/+3
| | | | | * txr.1: Clarify that both sort and nsort are not stable for vectors and strings.
* configure: capitalize diagnostic line.Paul A. Patience2024-01-031-1/+1
| | | | * configure: Capitalize first word "detecting" of diagnostic line.
* configure: normalize spacing in diagnosticsPaul A. Patience2024-01-011-14/+14
| | | | | * configure: Add space after ellipses where missing, and prefer putting the space in the initial printf.
* iter_begin: gc problem.Kaz Kylheku2024-01-011-0/+2
| | | | | | | | | | Also affects seq_begin. * lib.c (seq_begin, iter_begin): We must gc_protect the incoming obj also, not only the iter. Both these pointers are in the seq_info_t structure which is no longer used at the time the iterator is being allocated by the call to cobj, and so may be prematurely garbage collected.
* configure: fix for BSD grep.Paul A. Patience2024-01-011-2/+2
| | | | | * configure: Pipe output of strings into grep in endianness test, like is done for ubsan.
* Version 293.txr-293Kaz Kylheku2023-12-286-659/+709
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated.
* build: automate clean-up of shipped scanner and parserKaz Kylheku2023-12-285-9/+44
| | | | | | | | | | * Makefile (shipped): Copy the shipped materials unconditionally, rather than checking if they are different. If a patch exists for a shipped file, then apply it. * lex.yy.c.shipped, y.tab.c.shipped: Updated. * lex.yy.c.patch, y.tab.c.patch: New files.
* read-objects: clean up working, but odd code.Kaz Kylheku2023-12-281-3/+2
| | | | | | | | | | | | | This was prompted by a misleading indentation warning. * parser.c (read_objects_common): The indented statment "return error_return_val;" belongs with the if. This works anyway because if lisp_parse_impl returned unique_s, it means that either pi->syntax_tree is nao, or pi->errors is positive. So, let's take advantage of that and don't bother checking for pi->syntax_tree == nao. If unique_s was returned and there are no errors, we hit EOF and so break out of the loop.
* cygwin: run, sh: mangle termination status word.Kaz Kylheku2023-12-281-0/+10
| | | | | | | | | | * stream.c (run): On Cygwin, the spawnvp function is returning a 16 bit termination status word where the upper 8 bits is the termination status if the termination is normal, otherwise the lower 8 bits holds a termination signal. Let's massage it so that the function returns an integer termnation status, or nil if the termination was abnormal, same as we do on POSIX platforms with fork/wait.
* perm, rperm, comb, rcomb: test generic sequences, bugfixes.Kaz Kylheku2023-12-272-28/+36
| | | | | | | | | | | | | | | | | | | | | | | | perm doesn't generate items of the right type. We need to add the original sequence to the state vector and use make_like. The new generic sequence support in rperm is broken, too. * combi.c (perm_while_fun, perm_gen_fun_common): Rename p variable to vec. (perm_init_common): Rename to perm_init. Take one more argument and store in new fourth element of state vector. (perm_vec, perm_list, perm_str): Pass nil to new parameter of perm_init. (perm_seq_gen_fun): Use perm_list_gen_fun to get list permutations, and coerce each one to the same type as the sequence with make_like. (rcomb_seq_gen_fun): Remove redundant call to rcomb_gen_fun_common. The rcomb_list_gen_fun function is called, which does this already, so we lose every other sequence element. * tests/015/comb.tl: New tests.
* rcomb: support general sequences.Kaz Kylheku2023-12-271-1/+17
| | | | | | * combi.c (rcomb_seq_gen_fun, rcomb_seq): New static functions. (rcomb): Replace error throw in default case with call to rcomb_seq.
* comb: support general sequences.Kaz Kylheku2023-12-271-1/+16
| | | | | | | * combi.c (comb_seq_gen_fun, comb_seq): New static functions. (comb): Call comb_seq in default case rather than throwing error.
* comb: eliminate comb_hash_while_fun.Kaz Kylheku2023-12-271-8/+3
| | | | | | | | * combi.c (comb_hash_while_fun): Function removed. (comb_hash): For the while function, use the unwrapped state, and just comb_while_fun. The augmented state with hash is used only with comb_hash_gen_fun.
* rperm: support general sequences.Kaz Kylheku2023-12-271-6/+23
| | | | | | | | | | | | | | | | * combi.c (rperm_init): Take one more parameter. Allocate the state vector to three elements and put the extra value there. (rperm_list, rperm_vec, rperm_str): Pass nil for the extra value to rperm_init; these do not use it. (rperm_seq_gen_fun, rperm_seq): New functions. These use the extra value to store the original seq in the state, so that the elements of the output sequence can be converted to the same type of sequence as the input. (rperm): Replace error throw in default case with call to rperm_seq.
* rperm: change state representation to vector.Kaz Kylheku2023-12-271-8/+15
| | | | | | | | * combi.c (rperm_init): New static function. (rperm_while_fun, rperm_gen_fun): Retrieve state info from vector-based state rather than cons. (rperm_list, rperm_vec, rperm_str): Call rperm_init to allocate state.
* rcomb, perm, rperm: test.Kaz Kylheku2023-12-271-0/+317
| | | | * tests/015/comb.tl: New tests.