| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the make_like function, the list is converted to
string or buffer if the first element of the list
is a character, or integer. We need similar logic in
seq_build. We can make it better. When any item is
added which is incompatible, we can convert what we
have so far to a list, change the seq_build type
to list, and keep going.
* lib.c (seq_build_convert_to_list): New static
function.
(seq_build_str_add, seq_build_buf_add): If the item
is incompatible, convert the string or buffer to
a list and pass to seq_build_convert_to_list.
Then call bu->ops->add to add the item, now as a list.
(seq_build_buf_pend): Function removed.
(sb_buf_ops): Use the seq_build_generic_pend function
for the pend operation. This is because we have to
check each item one by one; we cannot use replace_buf.
|
|
|
|
|
|
|
| |
* lib.c (seq_build_struct_finish, seq_build_carray_finish):
These functions are still wrongly assuming that the list
is finished by nreverse. We intead call seq_build_list_finish
for that, which puts the list back into bu->obj.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.h (struct seq_build): New member, self.
(struct seq_build_ops): Remove self parameter from
pend function.
(seq_build_init, seq_pend): Declarations updated.
* lib.c (seq_build_generic_pend): Drop self parameter,
take the value from structure.
(seq_build_buf_pend): Drop self parameter.
(seq_build_init): New self parameter. Pass recursively.
(seq_pend): Self parameter dropped.
(rem_impl, rem_if_impl, keep_keys_if, separate, separate_keys):
Pass self to seq_build_init.
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_build_list_add, seq_build_list_finish):
We use the trick that bu->obj (if not nil) points
to the tail cons cell of the list being built, and
the cdr of that tail always points back to the head.
To finish the list, all we do is nil out that head
pointer, so the list is properly terminated, and then
plan the head as bu->obj.
|
|
|
|
| |
* lib.h (struct seq_build): Remove inf member.
|
|
|
|
| |
* lib.c (separate_keys): Rewrite using seq_info and seq_build.
|
|
|
|
|
| |
* lib.c (separate): switch statement with type-specific
coding replaced with generic sequence iteration and building.
|
|
|
|
|
|
| |
* lib.c (seq_build_init): Replicate a feature of make_like:
if the reference object is an iterator, then we recurse: we
initialize according to the object it is iterating.
|
|
|
|
|
| |
* lib.c (keep_keys_if): Replace with generic sequence
iteration and building.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* 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.tl (%quips%): New dad humor.
|
|
|
|
|
| |
* txr.1: Fix typo: for -> form; add missing leading
indentation in example.
|
|
|
|
|
|
| |
* stdlib/compiler.tl (simplify-variadic-lambda): Use
cons-count to find occurrences of the rest variable
rather than flatten and count.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* stdlib/compiler.tl (simplify-variadic-lambda): Remove
work-around where two patterns are combined with or,
expressing it the way it wants to be.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
* stdlib/compiler (lambda-apply-transform): Fix
misleading indentation.
|
|
|
|
|
| |
* txr.1: Under Pattern-Matching Notation: subject-verb
agreement.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.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.
|
|
|
|
| |
* stdlib/quips.tl (%quips%): New entry.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* txr.1: The source argument of mmap is not adequately
documented. It can be an integer descriptor, stream or
filename string.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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.
|
|
|
|
|
|
|
|
|
|
|
| |
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.c (link_wrap_common): Cast the follow_link
argument to void in the #else case to suppress warning.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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/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.
|
|
|
|
|
|
|
| |
OpenBSD is missing RLIMIT_AS.
* sysif.c (sysif_init): Register rlimit-as variable only if RLIMIT_AS is
defined.
|
|
|
|
| |
* txr.1: Fix markup of syntax, invalid due to missing space.
|
|
|
|
|
| |
* txr.1: Clarify that both sort and nsort are not stable
for vectors and strings.
|
|
|
|
| |
* configure: Capitalize first word "detecting" of diagnostic line.
|
|
|
|
|
| |
* configure: Add space after ellipses where missing, and prefer putting
the space in the initial printf.
|
|
|
|
|
|
|
|
|
|
| |
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: Pipe output of strings into grep in endianness test, like
is done for ubsan.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|