| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Using Lisp types for lengths, indices and buffer sizes
has been awkward due to all the conversions. The
code in buf.c and other code elsewhere that touches
buffers, overall improves when we revise this
decision. Mostly there are fewer conversion from
Lisp to C which require a type check and self symbol
for error diagnsotis, like c_unum(len, self).
In a few places, there are conversions in the other
direction that were not needed before, like
unum(b->len). These are simpler and faster.
* lib.h (struct buf): Members len and size change
from val to ucnum (pointer-sized unsigned integer).
* gc.c (mark_obj): No need to do anything with BUF any
more; it has no Lisp object references.
* buf.c (BUR_BORROWED): New preprocessor symbol. Because
the allocation size can no longer be nil to indicate that
the buffer is borrowed (the buffer object doesn't own
the memory) we use this value instead: the highest value
of the ucnum type.
(buf_check_alloc_size): len parameter changes from cnum
to ucnum. Defends against the BUF_BORROWED value.
(buf_check_index): Returns ucnum rather than cnum.
(err_oflow): NORETURN attribute added to prevent some spurious
compiler warnings.
(prepare_pattern): Drop c_unum conversion of len.
(make_buf): Some locals change from cnum to ucnum.
We lose an unnecessary conversion.
(init_borrowed_buf): Take len as ucnum rather than val.
Use BUF_BORROWED value for allocated size to indicate
borrowed status.
(make_borrowed_buf): Take len as ucnum.
(make_duplicate_buf, make_owned_buf): Take len as ucnum,
and take a self argument. Check for the size being
BUF_BORROWED and reject.
(make_ubuf): Parameter renamed. Lose a conversion from
ucnum to val.
(copy_buf): Check for allocated size being BUF_BORROWED
to distinguish the two cases, rather than it being nil
or not.
(buf_shrink): Simplifies: loses a C to Lisp integer
conversion, and no longer needs the local variable self.
(buf_trim): Reject borrowed buffers by noticing the
BUF_BORROWED value.
(buf_do_set_len): len param becomes ucnum. Two Lisp-to-C
integer conversiond disappear; one C-to-Lisp moves
elsewhere in the code.
(buf_set_length): Use buf_check_len to check and
convert incoming len to ucnum. This is an improvement
over the previous approach of letting buf_do_set_len
to just rely on c_num conversions and their generic
diagnostics.
(buf_free): Check for borrowed buffer by comparing
allocated size to BUF_BORROWED constant.
(length_buf): ucnum to Lisp conversion now required here.
(buf_alloc_size): Check for alloc_size being BUF_BORROWED
and convert that to a nil return value. When returning
an integer size, we need a conversion to a Lisp integer.
(sub_buf): Use self symbol rather than lit("sub") when
obtaining buffer handle. Use buf_check_len to validate
the length and convert to C type.
(replace_buf): Some cnum local variables become ucnum.
We need a very careful comparison of w and l because
w remains signed while l is unsigned.
(buf_list): Substantially rewritten. We don't calculate
the length of the sequence upfront, but extend the
buffer as we add the elements to it.
(buf_move_bytes): size parameter changes from cnum
to ucnum. Lisp arithmetic replaced with C arithmetic;
conversions eliminated.
(buf_put_buf): Conversion eliminated in call to buf_move_bytes.
(buf_put_bytes): Function reduced to wrapper for
but_move_bytes, since it is almost identical. The only
difference is that it performs memcpy rather than memmove
which is not worth a separate function.
(buf_put_i8, buf_put_u8, buf_put_char, buf_put_uchar,
buf_get_i8, buf_get_u8): Simplified with C arithmetic
and fewer conversions; cnum use replaced with ucnum.
(buf_get_bytes): size parameter goes from cnum to ucnum.
Overflow check for p + size addition added.
(buf_print): Two conversions removed.
(buf_str_sep): Conversion removed.
(struct buf_strm): pos member changes from val to ucnum.
(buf_strm_mark): Do not mark p->pos, no longer a Lisp object.
(buf_strm_put_byte_callback): Lisp arithmetic removed,
but a unum conversion is needed now in calling buf_put_uchar.
That could be eliminated by not using the public interface.
(buf_strm_get_byte_callback): Eliminate buf_check_index to
validate the stream position; we simply check it against
b->len. Becomes simple one liner.
(buf_strm_get_char): Local variable index renamd to pos.
Two conversions from and to Lisp eliminated, leaving
no conversions.
(buf_strm_unget_byte): Local variable p renamed to pos and
changes from cnum to ucnum. Two conversions eliminated
leaving no conversions.
(buf_strm_fill_buf): Conversions eliminated. Check for the
allocated size being BUF_BORROWED, in which case we
fall back on using the length. Lisp arithmetic eliminated.
(buf_strm_seek): Offset calculation done with C arithmetic
and bounds checks.
(buf_strm_truncate): Check incoming len with buf_check_len
and convert to ucnum. Lisp arithmetic and conversions
eliminated; buf_do_set_len used instead of public interface
buf_set_length.
(buf_strm_get_error): Use C comparison rather than ge
function, and convert to t or nil result.
(buf_strm_get_error_str): Bug: do not call errno_to_string
since buffers don't talk to an operating system API that
uses errno. The only error condition is eof. Thus,
return either "eof" or "no error".
(make_buf_stream): Initialize pos to 0 rather than Lisp zero.
(swap32, buf_str, str_buf, buf_int, buf_uint, int_buf,
uint_buf): Conversions eliminated; int_buf and uint_buf use
C multiplication by 8. We know this doesn't overflow because
the MPI bignums restrict the number of bits to something
countable by a word.
(buf_compress, buf_decompress, str_compress, str_decompress):
Conversions eliminated.
(buf_ash, buf_fash, buf_and, buf_test, buf_or, buf_xor,
buf_not, buf_trunc, buf_bitset, buf_bit, buf_zero_p,
buf_count_ones, binary_width, buf_xor_pattern): Make
necessary adjustments, adding and/or elimiating conversions.
* buf.h (make_borrowed_buf, init_borrowed_buf, make_owned_buf,
make_duplicate_buf, buf_put_bytes): Declarations updated.
* lib.c (equal, less): Conversions eliminated in BUF cases.
* eval.c (map_common): Add self argument to make_owned_buf call.
* chksum.c (chksum_ensure_buf): len param changes from cnum
to ucnum. Conversions eliminated and use of lt() switches
to C less-than operator.
(sha1_stream, sha1_buf, sha1, sha1_hash, sha1_end,
sha256_stream, sha256_buf, sha256, sha256_hash, sha256_end,
md5_stream, md5_buf, md5, md5_hash, md5_end): Adjustments:
conversions eliminated.
(crc32_buf): Conversion eliminated.
* genchksum.txr: Changes to chksum.c actually made here.
* ffi.c (ffi_buf_in, ffi_buf_get, ffi_buf_d_in,
ffi_buf_d_get, buf_carray, put_carray, fill_carray,
put_obj, get_obj): Simplified with removal of
conversions.
(fill_obj): Necessary adjustments, leaving same
number of conversions.
* hash.c (equal_hash): Remove conversion from BUF case.
* rand.c (make_random_state): Remove conversion of seed
to Lisp integer.
(random_buf): Pass self to make_owned_buf.
* strudel.c (strudel_unget_byte, strudel_fill_buf):
Coversions removed, streamlining code.
* stream.c (iobuf_get, iobuf_put): We cannot overload
the len field with serving as a linked list since it's
no longer a pointer. We instead use the struct any
union member, which has a next pointer for this purpose.
Because "t.next" overlaps with "b.size", and we must not
clobber the size field, we save "b.size" by copying it
into "b.len". When pulling buffers from the iobuf_free_list,
we restore b.size from b.len. For good measure, We
add a bug_unless assertion that the size is the expected
one. I ran into a test case failure while working on this
due to the size being clobbered to zero, and subsequent
I/O with that zero-sized buffer being interpreted as EOF.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (str_compress, str_decompress): New functions.
(buf_init): str-compress, str-decompress intrinsics
registered.
* lib.[ch] (string_utf8_from_buf): New function.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_xor_pattern): New function.
(buf_init): Register buf-xor-pattern intrinsic.
* buf.h (buf_xor_pattern): Declared.
* lib.[ch] (unsup_obj): Change function to
external linkage and declare in header.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.[ch] (do_juxt, juxtv): Functions removed.
* eval.c (do_callf): New static function.
Implements callf without consing up an
argument list with juxt which is then applied
to the function. It's all done with a loop
which builds args on the stack.
(callf): Rewritten to use do_callf. We have
to convert the function list to dynamic
args, but that is more compact than all the
consing done by the removed juxt implementation.
(juxt): New static function: implemented trivially
using callf and list_f.
(eval_init): Change registration from removed juxtv
to juxt. Going forward, I won't be using the v
suffix on functions. That should only be used when
two versions of a function exist: one which takes
vargs, and one which takes C variable arguments
or something else like a list. Example: format
is a variadic C function with a ... in its
argument list. formatv takes a varg and is the
main implementation. vformat takes a va_list.
Leading v is the standard C convention, like
vsprintf. trailing v is the TXR convention for
a function that takes vargs, but only if it is
an alternative to one which doesn't.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register keep intrinsic.
* lib.[ch] (keep): New function.
* stdlib/compiler.tl (compiler comp-fun-form): Transform
two argument keep to keepqual.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We need a remove function that doesn't have an equality
suffix, analogous to member, pos, count.
* eval.c (eval_init): Register remove intrinsic.
* lib.[ch] (remov): New function.
Named this way to avoid clashing with the ISO C remove
function in <stdlib.h>.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The notation X..Y..Z now denotes an iterable range,
if X..Y is a valid iterable range on its own, and Z is a
positive integer. Z gives a step size: 1 takes every
element, 2 every other and so on.
* lib.c (seq_iter_get_skip, set_iter_peek_skip): New static
functions.
(si_skip_ops): New static structure.
(iter_dynamic): Function relocated earlier in file to avoid
forward declaration.
(seq_iter_init_with_info): When the iterated object is a
range, check for the to element itself being a range.
If so, it is potentially a skip iteration. Validate it
and implement via a skip iterator referencing a dynamic
range iterator.
* lib.h (struct seq_iter): New sub-union member, ul.skip.
We could use an existing member of type cnum;
this is for naming clarity.
* tests/012/iter.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register iterp intrinsic.
* lib.[ch] (iterp): New function.
* tests/012/iter.tl: New tests.
* txr.1: Document iterp. Update documentation for iter-more,
iter-item and iter-step to more precisely identify which
objects are valid arguments in terms of iterp and additional
conditions, and that other objects throw a type-error
exception. Fix wrong references to iter-more under
documentation for iter-item. Removed obsolete text specifying
that iter-step uses car on list-like sequences, a dubious
behavior removed in the previous commit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Another almost 16% speedup.
* lib.c (us_length_STR): New static function.
(string_extend): Use us_length_STR, since we know the
object is of type STR.
(us_string_extend_STR_CHR): New function.
(length_str): Handle STR case via use_length_STR.
* lib.h (us_string_extend_STR_CHR): Declared.
* stream.c (get_csv): Use us_string_extend_STR_CHR
instead of string_extend.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The malloc_usable_size use in the STR type actually makes
operations like string_extend substantially slower. It is
faster to store the allocated size locally.
Originally, on platforms that have malloc_usable_size,
we were able to use the word of memory reclaimed from
the string type to store a cached hash code. But that logic
was revereted in 2022, so there is no such benefit.
* configure (have_malloc_usable_size): Variable
removed. Test for the malloc_usable_size function
removed.
(HAVE_MALLOC_USABLE_SIZE, HAVE_MALLOC_NP): Do not define
these preprocessor symbols.
* lib.c (HAVE_MALLOC_NP_H): Do not test for this variale
to include <malloc_np.h>
(string-own, string, string_utf8, mkstring, mkustring,
string_extend, string_finish, string_set_code,
string_get_code, length_str): Eliminate #ifdefs
on HAVE_MALLOC_USABLE_SIZE.
* lib.h (struct wstring): Eliminate #ifdef on
MALLOC_USABLE_SIZE, so alloc member is unconditionally
defined on all platforms.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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,
lex.yy.c.shipped, lib.c, lib.h, linenoise/linenoise.c,
linenoise/linenoise.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/comp-opts.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 bumped to 2025.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We introduce a mapfun argument to these functions so that they
can additionally transform the accumulated values.
The keep-keys-if function is now implemented through the same
helper function as keep-if but with the mapfun argument
defaulting to a copy of the keyfun argument.
* eval.c (eval_init): Update registrations of remove-if,
keep-if and keep-keys-if to new arities of C functions.
* lib.c (rem_if_impl): Implement new optional mapfun
parameter.
(remove_if, keep_if): Add mapfun parameter.
(keep_keys_if): Implement via rem_if_impl, and add
mapfun argument. We do the defaulting of keyfun here,
so that we can then use that argument's value to default
mapfun.
* lib.h (remove_if, keep_if, keep_keys_if): Declarations
updated.
* tests/012/seq.tl: Couple of test cases exercising mapfun
argument of keep-if and remove-if.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Iterator rewinding is only used by the three functions isec,
isecp and diff, which can easily just re-initialize the
iterator.
* lib.c (seq_iter_rewind): Static function removed.
(seq_iter_init_with_info): Remove support_rewind argument, and
adjust all code referencing it on the assumption that it's zero.
(seq_iter_init_with_rewind): Static function removed.
(seq_iter_init, iter_begin, iter_reset, nullify, find, rfind):
Drop last argument from seq_iter_init_with_info.
(diff, isec, iescp): Use seq_iter_init rather than
seq_iter_init_with_rewind. Instead of seq_iter_rewind, just
reinitialize the iterator.
* lib.h (seq_iter_init_with_info): Declaration updated.
* eval.c (tprint): Drop last argument from seq_iter_init_with_info.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
zip and transpose should allow non-character data
when the leftmost column is a string, falling back
on making lists, like seq_build.
We can't use seq_build as-is because of the special
semantics of transpose/zip with regard to strings.
We introduce a "strcat" variant of seq_build
for this purpose.
* lib.c (seq_build_strcat_add): New static function.
(sb_strcat_ops): New static structure like sb_str_ops,
but with seq_build_strcat_add as the add operation,
which allows string arguments to be appended to the
string rather than switching to a list.
(seq_build_strcat_init): New function.
* lib.h (seq_build_strcat_init): Declared.
* eval.c (zip_strcat): New static function; uses
seq_build_strcat_init.
(zipv): Only recognize strings specially; all else goes
through the existing default case.
Strings use zip_strcat.
* tests/012/seq.tl: New test case.
* txr.1: Describe special semantics of zip/tranpose;
previously only documented in one example.
Clarify that the rows are only sequences of the
same kind as the leftmost column if possible,
otherwise lists. Remove text which says that it's an error
for the other columns to contain non-string, non-character
objects if the leftmost column is a string.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (int_str_wc): New function, made out of int_str.
This can be used by the parser to work with a wchar_t *
string without having to create a string object.
(int_str): Implemented in terms of int_str_wc.
* parser.l (grammar): Remove string_own calls from numerous
rule bodies that use int_str to return a number.
These rules now capture the wchar_t string, pass it to
int_str_wc and then immediately free it. Whereas string_own
allocates an extra object and leaves it to the garbage
collector.
* lex.yy.c.shipped: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): New intrinsic functions find-maxes and
find-mins.
* lib.[ch] (find_maxes, find_mins): New function.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): register intrinsics wheref, whereq,
whereql and wherequal.
* lib.c (wheref_fun): New static function.
(wheref, whereq, whereql, wherequal): New functions.
* lib.h (wheref, whereq, whereql, wherequal): Declared.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These functions find random cyclic permutations.
* eval.c (eval_init): Register cshuffle and cnshuffle
intrinsics.
* lib.c (nshuffle_impl): New static function, formed out of
nshuffle.
(nhuffle): Now wrapper around nshuffle_impl.
(shuffle): Also wraps nshuffle_impl rather than nshuffle.
(cnshuffle, cshuffle): New funtions.
* lib.h (cnshuffle, cshuffle): Declared.
* txr.1: Documented new functions. Also added warning
about limitations on permutation reachability in relation
to PRNG state size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Several seq_iter_t kinds of objects cannot be correctly
bitwise copied, because they point to an iterator object
that cannot be shared.
* lib.c (seq_iter_clone_op): New static function.
(si_hash_ops, si_tree_ops, si_oop_ops, si_fast_oop_ops):
Use seq_iter_clone_op, which uses the copy function
to duplicate it->ui.iter after doing a bitwise copy of
the structure.
* lib.h (seq_iter_ops_init_full): New macro.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.h (struct cobj_ops): New function pointer, clone.
(cobj_ops_init, cobj_ops_init_ex): Add clone argument to macros.
* lib.c (seq_iter_cobj_ops): Use copy_iter as the clone operation.
(cptr_ops): Use copy_cptr as clone operation.
(copy): Replace if statements by check whether COBJ has a clone
operation. If so, we use it to copy the object.
* struct.h (enum special_slot): New member, copy_m.
* struct.c (copy_s): New symbol variable.
(special_sym): Associate copy_m enum value with copy symbol.
(struct_init): Initialize copy_s with interned symbol.
(struct_inst_clone): New static function.
(struct_type_ops): Specify no clone operation via null pointer.
(struct_inst_ops): Specify struct_inst_clone as clone
operation.
* arith.c (psq_ops): Indicate no clone operation via null pointer.
* buf.c (buf_strm_ops): Likewise.
* chksum.c (sha1_ops, sha256_ops, md5_ops): Likewise.
* ffi.c (ffi_type_builtin_ops, ffi_type_struct_ops,
ffi_type_ptr_ops, ffi_type_enum_ops, ffi_closure_ops,
union_ops): Likewise.
(carray_borrowed_ops, carry_owned_ops, carray_mmap_ops):
Specify copy_carray as clone operation.
* gc.c (prot_array_ops): Indicate no clone operation via
null pointer.
* gzip.c (gzio_ops_rd, gzip_ops_wr): Likewise.
* hash.c (hash_iter_ops): Likewise.
(hash_ops): Specify copy_hash as clone operation.
* parser.c (parser_ops): Indicate no clone operation via
null pointer.
* rand.c (random_state_clone): New static function.
(random_state_ops): Use random_state_clone as clone function.
* regex.c (char_set_obj_ops, regex_obj_ops): Indicate no clone
operation via null pointer.
* socket.c (dgram_strm_ops): Likewise.
* stream.c (null-ops, stdio_ops, tail_ops, pipe_ops,
dir_ops, string_in_ops, byte_in_ops, strlist_in_ops,
string_out_ops, strlist_out_ops, cat_stream_ops,
record_adapter_ops): Likewise.
* strudel.c (strudel_ops): Likewise.
* sysif.c (cptr_dl_ops, opendir_ops): Likewise.
* syslog.c (syslog_strm_ops): Likewise.
* unwind.c (cont_ops): Likewise.
* vm.c (vm_desc_ops, vm_closure_ops): Likewise.
* tree.c (tree_ops): Use copy_search_tree for clone
operation.
(tree_iter_ops): Use copy_tree_iter for clone operation.
* genchksum.txr: Changes in chksum.c specified in one
place here.
* tests/012/oop.tl: Couple of new tests.
* txr.1: Documented.
|
|
|
|
|
|
| |
* eval.c (eval_init): Register copy-iter intrinsic.
* lib.[ch] (copy_iter): New function.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_iter_mark_oop, seq_iter_mark_cat): New static
functions.
(si_oop_ops, si_fast_oop_ops): Use seq_iter_mark_oop instead
of the generic one, because we need to mark the next field,
not only the iter.
(si_cat_ops): Use seq_iter_mark_cat, since we need to mark
only the second field, dargs.
* lib.h (seq_iter_ops_init_mark): New macro.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register permi intrinsic.
* combi.c (permi_get, permi_peek, permi_clone): New static
functions.
(permi_ops): New static structure.
(permi_iter): New static function.
(permi): New function.
* combi.h (permi): Declared.
* lib.h (struct seq_iter_ops): New function pointer, clone.
(seq_iter_ops_init, seq_iter_ops_init_nomark): Initialize
new member.
(seq_iter_ops_init_clone): New macro.
(seq_iter_cls): Existing external name declared.
(seq_iter_cobj_ops, seq_iter_mark_op): Previously internal
names declared external.
* lib.c (seq_iter_mark_op, seq_iter_cobj_ops): Static variables
become extern.
(seq_iter_clone): New static function.
(seq_iter_init_with_info): Use seq_iter_clone instead of assuming
we can trivially clone an iterator state bitwise.
|
|
|
|
|
|
| |
In this commit, output variables in the TXR Pattern language and
in TXR Lisp quasiliterals now support separator strings for values
that are strings and buffers. Values which are buffers appear
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register iter-cat intrinsic.
* lib.h (struct seq_iter): New union member dargs.
(iter_catv): Declared.
* lib.c (seq_iter_get_cat, seq_iter_peek_cat): New
static functions.
(si_cat_ops): New static structure.
(iter_catv): New function.
* tests/012/iter.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
| |
* lib.[ch] (lcons_force): New function.
* eval.c (eval_init): Register lcons-force intrinsic.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_append2, seq_appendv, seq_nconc2,
seq_nconcv): New functions.
(append2, appendv, nappend2, nconcv): Now implemented
using new functions.
* lib.h (seq_append2, seq_appendv, seq_nconc2,
seq_nconcv): Declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Because ranges can be iterated like sequences, and are
identified as vector-like, they have to support indexing.
However, ranges already have semantics as a function:
with a sequence argument, they slice it.
Let's put the semantics into a function called rangeref,
so it can be coherently documented.
* eval.c (eval_init): Register rangeref intrinsic.
* lib.c (generic_funcall): Range as a function works in
terms of rangeref.
(ref): Handle RNG case via rangeref.
(rangeref): New function.
* lib.h (rangeref): Declared.
* tests/012/seq.tl: New tests.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (do_pa_12_1_v, pa_12_1_v): Static functions removed.
(transposev, transpose): Functions removed.
* lib.c (transposev, transpose): Declarations removed.
* eval.c (join_f): New global variable.
(zip_fun, zipv, transpose): New static functions.
(eval_init): gc-protect join_f, and initialize it.
Registration of zip intrinsic goes to zipv rather
than transposev. sys:fmt-join and join registered
with help of global join_f rather than local.
* tests/012/seq.tl: New zip test cases.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Let's have both a seq_pend and seq_nconc, where seq_nconc
can reuse the pieces of list passed to it.
* lib.h (struct seq_build_ops): New member, nconc.
(seq_build_ops_init): Add nconc parameter and initializer.
(seq_nconc): Function declared.
* lib.c (seq_build_list_pend): Switch to list_collect_append,
otherwise mappend behaves destructively.
(seq_build_list_nconc): New function.
(sb_vec_ops, sb_str_ops, sb_buf_ops, sb_struct_ops,
sb_carray_ops): Use seq_build_generic_pend for nconc
operation.
(sb_list_ops): Use new seq_build_list_nconc for nconc
operation.
(sb_finished_ops): Use null pointer for nconc operation.
(seq_nconc): New function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We want to use the list_collect functions for consistency.
For instance, these functions allow an atom to be added
to an improper list if the terminating atom is a sequence.
(append '(1 . "abc") "d") yields (1 . "abcd").
* lib.h (struct seq_build): New member, tail.
* lib.c (seq_build_list_add): Use list_collect.
(seq_build_list_pend): Use list_collect_nconc.
(seq_build_list_finish): Nothing to do here, except
call seq_build_convert_to_finished since bu->obj
is the head of the list at all times now.
(seq_build_improper_add, seq_build_improper_pend):
Functions removed.
(sb_improper_ops): Structure removed.
(seq_build_convert_to_improper): Function removed.
(seq_build_convert_to_list): Different strategy needed
here now. The list just goes into bu->obj, and we have
to set up the tail to either point to the last cons
cell's cdr, or else to bu->obj if the list is empty.
(seq_build_init): Initialize bu->tail in the three cases
that set up list collection.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.h (struct seq_build): Remove inf member.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register mref intrinsic.
* lib.[ch] (mref): New function.
* stdlib/place.tl (sys:mref1): New place.
(mref): New place macro, defined in terms
of sys:merf1, ref place and mref function.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These are functions for testing whether a list or
sequence is shorter than a given integer. This is cheaper
than calculating the length of lists, which is in
some cases impossible if they are infinite.
A length-str-< function already exists, useful
with lazy strings.
length-< uses length-list-< or length-str-<
as appropriate
* lib.[ch] (length_list_lt, length_lt): New functions.
* eval.c (eval_init): length-list-< and length-<
intrinsics registered.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register hist-sort intrinsic.
* lib.c (gt_f): New global variable.
(hist_succ_f): New static variable.
(hist_succ): New static function.
(hist_sort): New function.
* lib.h (gt_f, hist_sort): Declared.
* tests/012/sort.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register nestd-vec-of and nested-vec
intrinsics.
* lib.[ch] (vec_allocate, vec_own, vec_init): New static functions.
(vector, copy_vec): Expressed in terms of new functions.
(nested_vec_of_v, nested_vec_v): New functions.
* args.[ch] (args_cat_from): New function.
* tests/010/vec.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The vargs typedef is underused. Let's use it consistently
everywhere.
* args.c,
* args.h,
* args.c,
* args.h,
* arith.c,
* eval.c
* ffi.c,
* gc.c,
* hash.c,
* lib.c,
* lib.h,
* parser.c,
* stream.c,
* struct.c,
* struct.h,
* syslog.c,
* syslog.h,
* unwind.c,
* vm.c,
* vm.h: All "struct args * declarations replaced with existing
"varg" typedef that comes from lib.h.
|
|
|
|
|
|
|
|
|
|
| |
* lib.[ch] (str_esc): New function.
* eval.c (eval_init): str-esc intrinsic registered.
* tests/015/esc.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The new function use-sym-as can bring a foreign
symbol into a package under a different name,
which is not that symbol's name. This is also
featured in a new defpackage clause, :use-syms-as.
With this simple relaxation in the package system,
we don't require package local nicknames, which is
more complicated to implement and less ergonomic,
because it doesn't actually vanquish the use of
ugly package prefixes on clashing symbols.
* eval.c (eval_init): Register use-syms-as.
* lib.c (use_sym_as): New function, made out of
use_sym.
(use_sym): Now a wrapper for use_sym_as.
* lib.h (use_sym_as): Declared.
* stdlib/package.tl (defpackage): Implement :use-syms-as
clause.
* tests/012/use-as.tl: New file.
* txr.1: Documented,
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: Detect all the new functions, with separate
tests for the unary and binary ones.
* arith.c (cbrt_s, erf_s, erfc_s, exp10_s, exp2_s,
expm1_s, gamma_s, j0_s, j1_s, lgamma_s, log1p_s, logb_s,
nearbyint_s, rint_s, significand_s, tgamma_s, y0_s, y1_s,
copysign_s, drem_s, fdim_s, fmax_s, fmin_s, hypot_s,
jn_s, ldexp_s, nextafter_s, remainder_s, scalb_s, scalbln_s,
yn_s, r_copysign_s, r_drem_s, r_fdim_s, r_fmax_s, r_fmin_s,
hypot_s, r_jn_s, r_ldexp_s, r_nextafter_s, r_remainder_s,
r_scalb_s, scalbln_s, r_yn_s): New symbol variables.
(not_available): New static function.
(cbrt_wrap, erf_wrap, erfc_wrap, exp10_wrap, exp2_wrap,
expm1_wrap, gamma_wrap, j0_wrap, j1_wrap, lgamma_wrap,
log1p_wrap, logb_wrap, nearbyint_wrap, rint_wrap,
significand_wrap, tgamma_wrap, y0_wrap, y1_wrap,
copysign_wrap, drem_wrap, fdim_wrap, fmax_wrap,
fmin_wrap, hypot_wrap, jn_wrap, ldexp_wrap,
nextafter_wrap, remainder_wrap, scalb_wrap, scalbln_wrap,
yn_wrap): New static functions.
(arith_set_entries, arith_instantiate): New static functions.
(arith_init): Initialize symbols and instantiate functions
via autoload mechanism. In a program that doesn't use the
functions, we suffer only the overhead of interning the symbols.
* lib.h (UNUSED): New macro for GCC unused attribute.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
@(push) is like @(output), but feeds back into input.
Use carefully.
* parser.y (PUSH): New token.
(output_push): New nonterminal symbol.
(output_clause): Handle OUTPUT or PUSH via output_push.
Some logic moved to output_helper.
(output_helper): New function. Transforms both @(output)
and @(push) directives. Checks both for valid keywords;
push has only :filter.
* parser.l (grammar): Recognize @(push similarly to other
directives.
* lib.[ch] (push_s): New symbol variable.
* match.c (v_output_keys): Internal linkage changes to external.
(v_push): New function.
(v_parallel): We must fix the max_line algorithm not to
use an initial value of zero, because lines can go negative
thanks to @(push). We end up rejecting the pushed data.
(v_collect): We can no longer assert that the data line
number doesn't retreat.
(dir_tables_init): Register push directive in table of
vertical directives.
* match.h (append_k, continue_k, finish_k): Existing symbol
variables declared.
(v_output_keys): Declared.
* y.tab.c.shipped,
* y.tab.h.shipped,
* lex.yy.c.shipped: Updated.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.[ch] (keep_keys_if, separate_keys): New functions.
* eval.c (eval_init): keep-keys-if, separate-keys intrinsics
registered.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
| |
This C++ regression snuck into in Version 286; I didn't
check C++ compilation.
* lib.h (container): Macro must use coerce not
convert because mem_t * isn't void *.
* gc.c (gc_prot_array_alloc): Likewise.
|