| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_put_bytes, buf_get_bytes): static functions
become external.
* buf.h (buf_put_bytes, buf_get_bytes): Declared.
* stream.c (get_line_as_buf): New fucntnion.
(stream_init): Registered get-line-as-buf intrinsic.
* stream.h (get_line_as_buf): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
| |
* genvim.txr (tl-sym): Recognize the contains symbol and
render it as the string "contain[s]". Vim thinks that
contains is reserved a keyword, anywhere in the syn keyword
line, and throws an error.
|
|
|
|
|
|
|
| |
* share/txr/stdlib/path-test.tl (do-path-test): Pass all
argument types to statfun, except if they are of type stat.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: the golden trick is simply to test
whether PS4 contains "+ ". PS2 is not a useful variable,
because even crappy old 1980's vintage System V shells
set that up. It turns out that Zsh in POSIX mode (when run as
/bin/sh) handles configuring and building TXR just fine.
And Zsh does set PS4 to "+ " in that mode. However, it
does not set PS2, unless run interactively. When run
interactively as /bin/sh, Zsh sets PS2 to "> ".
So, let us drop the Bash variable tests, and the test
for PS2 being "> " and only test PS4.
|
|
|
|
|
| |
* configure: everything works fine with ksh93, so let's add
ksh to list of shell to look for.
|
|
|
|
|
|
|
| |
* configure: There is a clue in the PS2 and PS4 variables.
If these are present and have the values "> " and "+ "
the shell could be Dash or newer NetBSD Ash, which
got PS4 circa 2004. The Solaris XPG shell also has these.
|
|
|
|
|
|
|
| |
* stream.c (w_fopen_mode): Add O_APPEND flag if
m.append is set.
(do_parse_mode): Set m.notrunc flag for append mode, so
O_TRUNC won't be added in w_fopen_mode.
|
|
|
|
|
|
| |
* parser.c (provide_completions): Recognize U+0080 and higer
characters as token constituents, allowing completion to
work for symbols which use these characters.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: If we determine we are running on Bash, then do
not re-execute. If re-executing, then look for CONFIG_SHELL
first, which is an Autoconf convention that some distros rely
on. Include dash in the fallback shell list because dash works
fine. Include more places in which to look for bash and dash.
Uses of txr_shell must be quoted now because it could take on
the value of CONFIG_SHELL which we don't control.
Print a trace message about re-executing. Print the message
about which shell we are running on earlier, before
parsing the variables and printing the baner.
Since we might not re-execute any more, we might not know the
exact name of the shell we are running on. That is difficult
and hacky to obtain, so instead we print an alternative
message that we are running on the original shell.
(gen_config_make): Only generate the SHELL Makefile variable
if txr_shell is set. If whatever shell we were run with is
good enough for the configure script, it's good enough for
Makefile recipes. Likely, the configure script was executed
directly, so that /bin/sh is that default shell and that is
what GNU Make will use by default.
|
|
|
|
|
|
|
|
|
|
| |
* regex.c (L1_fill_range, L2_fill_range, L3_fill_range): Bug:
when the arguments ch0 and ch1 indicate that a block is to be
filled entirely, we assume that the pointer is either null
or else a pointer to an allocated block, either of which we can
free and replace with a -1 pointer to indicate a full block.
However the pointer may already be -1, in which case we
wrongly pass that to free(). We must check for it.
|
|
|
|
|
|
| |
* regex.c (create_wide_cs): Add some Emoji ranges from
Plane 1, loosely following the Unicode 13.0 data given
in https://en.wikipedia.org/wiki/Emoji.
|
|
|
|
|
|
| |
* regex.c (create_wide_cs): Extend over the entire
supplementary ideographic plane U+2XXXX and
the tertiary one: U+3XXXX.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Updating the regex for matching code points corresponding to
wide and full width characters, with regard to the old
1998 document: http://www.unicode.org/reports/tr11-2/
More to follow.
I neglected to comment where the original data came from,
and neglected to comment it. In some cases it has more
coverage than the 1998 document; in some cases less.
* regex.c (create_wide_cs): Extending the 1100-115F range
to 11F9 to cover all of Korean Hangeul. Replace two
occurrences of 3000-303E with one 3000-303F.
Merge 3250-32FE with 3300-4DB5, and extend to 4DBF.
Add private use range E000-E757.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this patch, if open-file blocks (for instance on a FIFO
or device), it is interruptible. In the listener, the
operation can be aborted with Ctrl-C now.
* stream.c (w_fopen_mode): If we HAVE_FCNTL, then handle all
file opening via open + fdopen, rather than fopen. On
platforms where we use fopen, interruptibility won't work.
The fopen function cannot be abandoned via an exception thrown
from a signal handler because it performs memory allocation.
Because we need a temporary UTF-8 string to do the open,
which might be abandoned by a signal, let's move the string to
the stack via alloca, and free the original, so we don't have
to set up unwinding to free it.
|