| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
| |
* lib.c (search_list, rsearch_list): When the key has a bad
type, don't report the seq object in its place.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The vscat function is white-box copy of cat_str, with just the
iteration over the inputs done differently, and without the
support for separators that are characters instead of strings
(which was added to cat_str after vscat was forked.
In this patch, the common logic underlying both functions is
factored out into a small ad-hoc "struct cat_str" object which
maintains the state and provides the operations to measure the
pieces of the string, allocate the space, copy the pieces
together and produce the resulting object.
The motivation here isn't just to reduce duplication. I would
like a more efficient function for catenating strings which
takes a "struct args *", not requiring a list to be consed up.
* lib.c (struct cat_str): New struct type.
(cat_str_init, cat_str_measure, cat_str_alloc, cat_str_append,
cat_str_get): New static functions.
(cat_str, vscat): Considerably shorten by using the above
functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fossies administrator Jens alerted me to some typos.
* txr.1: Fix two instances of alphanumeric being hyphenated,
and one case of invocable being rendered as invokable.
* linenoise/linenoise.c (struct lino_state): Misspelled
"buffer" in a comment. One other comment typos in this file is
from the original code, so it stays: who needs yet another
merge conflict? Not touching the original typo in example.c,
either.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (rt_assert_fail, me_assert): New static functions.
(eval_init): assert macro and sys:rt-assert-fail function
registered.
* lib.c (func_n4ov): New function.
* lib.h (func_n4ov): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): If opt_compat is 237 or less, make sort
and shuffle destructive.
* share/txr/stdlib/getopts.tl (opthelp): Revert previous
change, restoring use of copy-list and use nsort instead of
sort, so the function is not affected by the 237 compatibility
being turned on.
* txr.1: Add compatibility notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I'm fixing a historic mistake copied from ANSI Lisp,
which trips up language newcomers and sometimes even
experienced users.
The function innocently named sort will now return newly
allocated structure. The function previously called sort will
be available as nsort (non-consing/allocating sort).
The shuffle function also becomes pure, and is accompanied by
nshuffle.
* eval (me_op): Continue to use destructive sort in this
legacy code that is only triggered in very old compat mode.
(eval_init): Registered nsort and nshuffle.
* lib.c (nsort, nshuffle): New functions introduced, closely
based on sort and shuffle.
(sort, shuffle): Rewritten to avoid destructive behavior: work
by copying the input and calling destructive counterparts.
(sort_group): Continue to use destructive sort, which is safe;
the structure is locally allocated. The sort_group function
has pure semantics.
(grade): Likewise.
* lib.h (nsort, nshuffle): Declared.
* share/txr/stdlib/getopts.tl (opthelp): Replace an instance
of the (sort (copy-list ...)) pattern with just (sort ...).
* tags.tl (toplevel): Continue to use destructive sort to sort
tags before writing the tag file; the lifetime of the tags
list ends when the file is written.
* tests/010/seq.txr: Switch some sort calls to nsort to keep
test case working.
* txr.1: Documented.
|
|
|
|
|
|
|
|
| |
* lib.c (sort, shuffle): Switch to seq_info. For consistency
with sort, shuffle now handles hashes in the same peculiar
way.
* txr.1: Document hash behavior for sort and shuffle.
|
|
|
|
|
|
|
| |
* sysif.c (isatty_wrap): New function.
(sysif_init): Register isatty intrinsic.
* txr.1: Documented.
|
|
|
|
|
| |
* txr.1: Remove manually added angle brackets on <form>.
Fix inappropriate use of << and >>.
|
|
|
|
|
| |
* configure: move the section of the script which
produces ./reconfigure after the help processing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I've noticed that the January 9, 2020 commit "gc: obtain stack top using
alloca" triggers spurious retention when compiling with HAVE_VALGRIND.
The finalization test case tests/012/fini.tl breaks because the expected
finalizers are not called. Changing the (sys:gc) call to two calls to
(sys:gc 1) makes it pass.
The culprit seems to be the inlining of the complex function sweep
into gc. It has local variables for which spaces has to be reserved,
which are not used until after mark() is called; likely the values
in those spaces are picked up by the stack scan.
Let's make sure that functions called out of gc() are not inlined.
* gc.c (mark, sweep, prepare_finals, call_finals): Mark NOTINLINE.
|
|
|
|
|
| |
* lib.c (funcall1, funcall2, funcall3, funcall4): Add forgotten
argument zaps in the case that routes to generic_funcall.
|
|
|
|
|
|
| |
* lib.c (countqual, countql, countq, count_if, some_satisfy,
all_satisfy, none_satisfy): Convert from list iteration to
seq_info.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler compile): Open up the
main caseq statement for handling symbols other than just
special operators. Now we handle the compiler-only special
operator sys:ift here, as well as the special casing for call
and apply. Function calls are handled as the fallback case
here now.
(compiler call-fun-form): Remove the checking for ift, and for
call, apply and usr:apply. Only regular case function calls
are handled here now.
(compiler comp-apply-call): New method dedicated for compiling
calls to the call, apply or usr:apply functions, dispatched
directly out of compiler compile.
|
|
|
|
|
|
|
|
| |
The compile function doesn't need to expand because the input
is a function that has already been expanded.
* share/txr/stdlib/compiler.tl (compile): Pass the second
argument to compile-toplevel to suppress expansion.
|
|
|
|
|
|
|
| |
* eval.c (lookup_fun): A lambda expression must be expanded
before being turned into a function.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is what the recent load-time changes were grooming the
compiler toward. When we compile a lambda, we can look at the
function and variable refernces it is making. If the lambda
makes no lexical function or variable references, we can lift
that lambda into load time, so that it's instantiated once and
then re-used out of a D register. Effectively, it becomes a
top-level function.
* share/txr/stdlib/compiler.tl (compiler comp-lambda-impl):
New method, formed by renaming comp-lambda.
(compiler comp-lambda): Turned not wrapper for comp-lambda
impl which compiles the lambda, and checks for the conditions
for hoisting it into load time, which is currently done by
generating the sys:load-time-lit form around it and re-compiling.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler comp-for): If a for
loop occurs in the top level, or inside a load-time, then we
don't want to suppress the semantics of load-time for any
parts of the loop that are repeatedly evaluated. The
programmer may be doing that specifically to hoist those
calculations out of the loop. We thus bind *load-time* to nil
after compiling the initializing and test expressions.
* txr.1: New paragraph in Notes for load-time, mentioning
compiler treatment of loops and lambda. The language is
deliberately general rather than being specifically about the
for loop, because several loop constructs compile to the for
loop, and that is also subject to future changes.
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compile-toplevel): Bind
*load-time* to t, because of course initially we are in the
top level, where load-time can be eliminated.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler comp-load-time-lit):
Don't hoist constant expressions into load-time, since they
already get hoisted into a D register. Otherwise we just end
up generating load-time code that moves from one D register to
another.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
load-time forms nested in load-time forms have no special
semantics; it's wasteful to separately hoist them into load
time and store their value in their own D register.
We must be careful: this is not true if a nested form occurs
in a lambda.
* share/txr/stdlib/compiler.tl (*load-time*): New special
variable.
(compiler comp-lambda): Bind *load-time* to nil around
the compilation of the lambda, so load-time forms in the
lambda are hoisted to load time, even if the lambda itself
is wrapped in a load-time form.
(compiler comp-load-time-lit): Bind *load-time* true around
the compilation of the form. If *load-time* is already true,
then skip the special load-time logic and just compile the
enclosed form; the surrounding load-time compilation is taking
care of the load-time hoisting.
* txr.1: Document that load-time forms nested in load-time
forms don't do anything, except in the lambda case.
|
|
|
|
|
| |
* txr.1: Fix typos and incorrect symbol under put-buf and
fill-buf method.
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler comp-load-time-lit):
When compiling the load-time argument expression, indicate the
allocated D register as the destination, rather than using a
freshly allocated T register. Now we need an instruction to
move into the D reg only if the fragment chose a different
register.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/socket.tl (sys:in6addr-condensed-text):
Rewrite with regex based implementation that formats
the number without condensing. This one has better
semantics in that it finds the longest run of 0.0..0
to replace, rather than the leftmost. Ignoring this
semantic difference, it also has better average performance on
pseudo-random addresses, with similar performance on
addresses with long condensable 0's. The original algorithm
has a significantly poorer average case on random addresses,
but better best case on condensable zeros like 1::1.
The new algorithm could improve further with future work to
make regexes faster.
|
|
|
|
|
|
|
|
| |
The str-in6addr and str-in6addr-net functions mishandle
the zero address, rendering it as ":" instead of "::".
* share/txr/stdlib/socket.tl (sys:in6addr-condensed-text):
Test for the degenerate case and map it to "::" output.
|
|
|
|
|
| |
* txr.1: A zero-width bit-field placed as the last member
can have an effect on the structure; let's mention it.
|
|
|
|
|
|
|
|
| |
* txr.1: Rewriting the last two sentences to fix the wrong
claim of its last two sentences, which contradicts the correct
statement in the the previous paragraph. The statements are
only correct about big-endian, not about both types of
machine.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_i8_rput, ffi_i8_rget, ffi_u8_rput, ffi_u8_rget,
ffi_i16_rput, ffi_i16_rget, ffi_u16_rput, ffi_u16_rget,
ffi_i32_rput, ffi_i32_rget, ffi_u32_rput, ffi_u32_rget,
ffi_char_rput, ffi_char_rget, ffi_uchar_rput, ffi_uchar_rget,
ffi_bchar_rget, ffi_short_rput, ffi_short_rget,
ffi_ushort_rput, ffi_ushort_rget, ffi_int_rput, ffi_int_rget,
ffi_uint_rput, ffi_uint_rget, ffi_long_rput, ffi_long_rget,
ffi_ulong_rput, ffi_ulong_rget, ffi_wchar_rput,
ffi_wchar_rget, ffi_be_i16_rput): Add casts to suppress
warnings about unused tft and self.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Querying the :fd stream property is equivalent to calling the
stream-fd function. Streams have a C virtual function get_fd,
so implementing :fd in their getprop functions is redundant
functionality. The stream-getprop function can test for
:fd and call stream-fd, so the stream implementations don't
have to deal with the :fd property.
Also, there are still places in the code base that are using
stream_getprop to get the file descriptor, instead of calling
stream_fd.
If we fix all this, then fd_k remains referenced only in
a very small number of places.
* socket.c (dgram_get_prop): Don't handle :fd any more.
* stream.c (unimpl_get_fd): Static function removed.
(fill_stream_ops): Default the get_fd function to null_get_fd
instead of unimpl_get_fd, so it doesn't throw.
Even a stdio stream don't throw; when the file is closed,
it returns nil.
(stdio_get_prop): Don't handle :fd any more.
(stream_get_prop): Handle :fd here. If the stream has a get_fd
function that isn't null_get_fd, then call it. Only if the
stream doesn't have a get_fd function, fall back on its
get_prop function.
* sysif.c (mkdir_wrap, poll_wrap, simulate_setuid_setgid):
Call stream_fd instead of stream_get_prop.
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_shrink): Convert len to alloc size using c_unum,
which will reject negative values that will implicitly convert
to a wrong/huge size.
* lib.c (upcase_str, downcase_str): Similar reasoning.
(sub_vec): nelem is a size_t, so use unum on it, rather
than num.
|
|
|
|
|
|
|
| |
* ffi.c (carray_dup, carray_blank, carray_ref, carray_refset,
carray_replace, carray_pun): Refer to "carray" rather than
"array" in diagnostic messages, which is more accurate and
consistent with newer diagnostics added in previous patch.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The carray type is hereby reviewed for and repaired of issues
related to the nelem member of struct carray using negative
values to indicate "unknown carray size".
* ffi.c (struct carray): The artype becomes a two-element
array of values, so a carray can have a cache of separate
null-terminated and non-null-terminated array type
descriptors. This way, we get rid of the dirty trick of
mutating one type.
(carray_mark_op): Mark the two-element artype.
(make_carray): Initialize two-element artype to nil.
(carray_set_length): Cache invalidation: reset both elements
of artype to nil, because the type includes length
information, which may now be wrong.
(copy_carray): Throw exception if asked to copy carray of
unknown length. This would happen in carray_dup anyway,
but at least the diagnostic refers to copy-carray.
(buf_carray): Avoid calling make_duplicate_buf with negative
bytes value when the carray has unknown length; diagnose.
(carray_ref, carray_refset): Don't translate negative index
values if the length is unknown.
(carray_sub, carray_replace): If the operation requires
use of the length, and it is unknown, throw an
exception.
(carray_ensure_artype): Take a null_term paramter that is 0
or 1, and use it as an array index into artype to set up the
correct type, with the correct value of the null_term
member that is henceforth not mutated.
(carray_get_common, carray_put_common): Pass the null_term
argument down to carray_ensure_artype.
Remove the mutation of the null_term member of the type
structure.
|
|
|
|
|
|
|
| |
* sysif.c (poll_wrap): Allocate poll array using alloca so it
will be disposed of naturally if an exception occurs.
Place sig_save_enable and sig_restore_disable around poll call
to allow non-deferred handler execution.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: cosmetics: change HAVE_SYS_SELECT to HAVE_SELECT,
and log that the function rather than the header is being
detected.
* socket.c (fd_timeout): New function, implemented using
poll or select.
(to_connect): select logic replaced with fd_timeout. Bug
fixed: connect requires polling for writability, not
readability. If poll and select are not available,
ignore timeout argument.
(sock_accept): Use fd_timeout; fall back on non-timed-out
accept if poll or select not available.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* tests/012/ifa.tl: The "ambiguous" test case is not ambiguous
at all. The reason it was yielding :error previously was not
due to the ifa macro identifying an ambiguity but due to the
funcion < not accepting nil arguments. Since < now does accept
nil arguments, this test broke. Fixing this test, and adding
one that tests for the ambiguous case: multiple it-candidates
being rejected by ifa at expansion time.
* tests/common.tl (vtest): This macro requires maintenance. To
test for expansion-time failure, we must use expand, not just
macroexpand. In this case, the (ifa ...) macro call is wrapped
in a (let ...) so macroexpand won't do it. Secondly, the
expected value is an quote expression that must be evaluated
if we need its value in vtest itself. Otherwise it won't
compare equal to :error, since it is actually (quote :error).
|
|
|
|
|
|
|
|
|
|
| |
Time for some spring cleaning.
* args.c, arith.c, buf.c, cadr.c, chksum.c, debug.c, ftw.c,
gc.c, gencadr.txr, glob.c, hash.c, lisplib.c, match.c,
parser.c, parser.l, parser.y, rand.c, signal.c, stream.c,
strudel.c, syslog.c, tree.c, unwind.c, utf8.c, vm.c: Numerous
unnecessary #include directives removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The MP_DEBUG macro controls the visibility of definitions that
are not used anywhere.
* mpi/mpi-config.h (MP_DEBUG): Removed.
* mpi/mpi.c (DIAG): Macro and surrounding section controlled
by #if MP_DEBUG removed.
* mpi/mpi.h (MP_IOFUNC): Definition controlled by MP_DEBUG
removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The c_unum and unum functions are fairly often needed
and and are closely related to c_num and num, which have
always been declared in lib.h even though they live in
arith.c. Files not doing arithmetic are including "arith.h"
just for the sake of c_num or unum.
* arith.h (c_unum, unum): Declarations removed.
* lib.h (c_unum, unum): Declarations moved here.
* chksum.c, debug.c, stream.c, strudel.c, sysif.c, vm.c:
These files no longer require #include "arith.h" as a result,
which is therefore removed.
|
|
|
|
|
|
| |
* lib.c (symbol_needs_prefix): If the name is an empty string,
the symbol needs a prefix. Otherwise it disappears in the
output.
|
|
|
|
|
|
|
|
| |
* tags.tl (fake-load): When the file doesn't end in .tl, we
are only trying it with the .tl suffix, without falling back
on the original name. And we are doing that in an ignerr, so
the nil object will be used as a stream. This cause stdin to
be read when the function encounters a dangling symlink.
|
|
|
|
|
| |
* parser.l (YY_INPUT): Must use coerce because we are changing
from char * to unsigned char *.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As a result of this change, the startup time is reduced.
The command txr -e '(compile-toplevel nil)' shows a 54%
speedup: around 110 milliseconds down from around 170.
Programs that read large amounts of TXR Lisp data will
benefit.
* parser.l (YY_INPUT): Use new get_bytes function instead of
get_byte to read a buffer at a time.
* stream.c (get_bytes): New function.
* stream.h (get_bytes): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this commit, the put_buf and fill_buf stream virtual
functions are changed to operate directly on a low-level
buffer, rather than a stream. This will allow these functions
to be used for improving the performance of I/O operations
that are not related to buffer objects.
* stream.h (struct strm_ops): Change type signature of put_buf
and fill_buf members. The lengths and iszes are ucnum.
The return value is ucnum. The buffer is passed as a pointer
and length, rather than a buffer object.
* stream.c (unimpl_put_buf, unimpl_fill_buf, generic_put_buf,
generic_fill_buf, stdio_put_buf, stdio_fill_buf,
delegate_put_buf, delegate_fill_buf): Adjust to
new interface.
(put_buf, fill_buf, fill_buf_adjust): Pull the poitner and
size from the buffer and pass those down to the virtual
functions rather than the buffer itself. Convert ucnum return
value to val.
* strudel.c (strudel_put_buf, strudel_get_buf): The struct
delegate interface doesn't change. The put-buf and fill-buf
methods still operate on buffer objects. To glue that with the
new low-level interface, we use the init_borrowed_buf trick
that is was first used in ffi.c: temporary buf objects are
efficiently allocated on the stack, pointing to the same
memory that is coming down from the stream operation.
* txr.1: Document the new restrictions on the buf argument of
the put-buf and fill-buf stream delegate methods.
Since the buf not a heap object, it cannot be used after the
method returns.
|
|
|
|
|
|
|
|
| |
* arith.c (numneqv): Do not unconditionally cons all the
arguments into a list. If the arguments structure has no
trailing list, then just loop over the arguments in the arg
array. Only cons all the arguments into a list if there is a
trailing list.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (seq_nueq, seq_lt, seq_le): New
static functions.
(gt, lt): Handle sequences via seq_lt.
(ge, le): Handle sequences via seq_le.
(numeq): Handle sequences via seq_eq.
* txr.1: Documented, and also added missing documentation
about comparison of ranges by these functions, fixed
mistake in the syntax (> listed twice) and added
some notes about symmetry of > >= and < <=.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_info): Ensure the type field in the returned
structure is inintialized. We are neglecting this when the
type is COBJ, initializing only the kind field. This makes
the in function behave unreliably over arguments that
are hash tables, or vector-like sequences (objects with
a length function or the carray type). Several other functions
will behave unreliably for vector-like sequences: reverse,
find, rfind, pos, rpos and tprint.
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (%bin-op%): Specify default
value argument to relate so that arguments not found in
%nary-ops% will match to nil. Otherwise the code in
comp-fun-form rewrites all two-argument function calls through
this relation, resulting in a bit of wasted consing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/compiler.tl (compiler comp-if): The two and
three argument cases assume that if the test is a constant
expression, the consequent "then" should be unconditionally
taken. The correct behavior is to evaluate the constant,
which could yield nil. I checked which library code changes
after this fix, and found that a number of (defset ...)
forms are generating different, shorter code.
This is due to (if ',restpar (if (consp ,restpar) ...))
in defset-expander. The intent there was to eliminate the
inner if code entirely if respar is nil (there is no rest
parameter); due to this bug, the code elimination didn't
happen. The behavior is nevertheless correct because the
code does nothing if restpar is nil.
|