| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
* txr.1: Under call function, document that callable
objects need not be functions; the dwim operator
description has the details.
Fix a formatting problem in the dwim operator
syntax synopsis. Under dwim, clarify in more detail
that the behavior for various objects are a consequence
of their function calling semantics, rather than
inherent in the dwim operator.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 (list_vec): use ucnum rather than int
for the index and length variables.
|
|
|
|
|
|
| |
* lib.c (unique): Build output using seq_build_t, rather
than consing up a list which is then converted to the desired
sequence type.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (MAP_ALLOCA_LIMIT): New preprocessor symbol.
(map_common): If the number of args is greater than
MAP_ALLOCA_LIMIT, then allocate the array of seq_iter_t
structures from chk_malloc rather than alloca.
In case an exception might be thrown during the execution
of this function, we bind that memory to a buf object.
If we return normally, we call the new function buf_free
to release it. Otherwise we rely on the garbage collector.
* buf.[ch] (buf_free): New function.
* tests/012/seq.tl: Test case which hits this behavior.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
| |
* txr.1: All arguments that give a list of indices into a
sequence are called index-seq, because they are not required
to be lists. Only the COMPATIBILITY section refers to
index-list arguments, mentioning that those arguments are
now called index-seq.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (partition_func, split_func, split_star_func):
Indices passed through lazy cons are now iterator,
rather than a sequence accessed via car and cdr,
which is inefficient for nonlists.
(partition-split-common): Use iter-begin to convert
indices to iterator, which becomes the cdr field of
the lazy cons.
* txr.1: Update documentation for these functions to clarify
that the second argument is a sequence. The inaccurate
text claiming that "if the second argument is an atom
other than a function" is rewritten. This doesn't describe
the behavior that is implemented, where the test applied
is seqp, not atom. The indices can be a vector of integers,
which is an atom.
|
|
|
|
|
| |
* lib.c (partition_if_func): Instead of list_collect_decl
and make_like, use seq_build.
|
|
|
|
|
|
|
|
| |
* lib.c (partition_by_func): The seq object is now
an iter object: use iter_more, iter_item and iter_step
rather than non-null test, car and cdr.
(partition_by): Obtain iterator for sequence using
iter_begin, and use that in its place.
|
|
|
|
|
| |
* lib.c (partition_by_func): Use seq_build instead of
list_collect_decl and make_like.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.c (sb_vec_ops): fix indentation.
|
|
|
|
|
|
| |
* lib.c (seq_build_struct_finish, seq_build_carray_finish):
Do not call seq_build_convert_to_finished, since
seq_build_list_finish has already done that.
|
|
|
|
|
|
|
|
| |
* lib.c (seq_build_improper_finish): Function removed.
(sb_improper_ops): Replace seq_build_improper_finish
with null pointer. The seq_finish function checks for
null and avoids calling, so we don't need the noop
implementation.
|
|
|
|
|
|
|
|
| |
* lib.c (seq_build_convert_to_finished): New function.
(seq_build_list_finish): call seq_build_convert_to_finished.
(sb_finished_ops): New static struct. All operations
except mark are null pointers so this will crash if
used.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (mapcar): Implement with seq_iter and seq_build,
rather than relying on mapcar_listout and make_like.
(mappend): Replace list_collect_decl and make_like
with seq_build.
* eval.c (map_common): Replace list_collect_decl and
make_like with seq_build. The collect_fn is now a pointer
to either seq_add or seq_pend rather than list_collect
or list_collect_append.
(mapcarv, mappendv): Pass seq_add and seq_pend to
map_common, rather than list_collect and list_collect_append.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To be useful for some operations, the seq_build framework
must handle the pend operation on lists specially.
The appended piece must only be treated as a sequence if
it is a cons. Moreover, if it is an atom, or of it is
an improper list, then the list terminates. Subsequent
add and pend operations must fail. The atom must appear
as the terminator. We meet these objectives by switching
the object's operations, sb_list_ops, to a new set of
operations, sb_improper_ops.
* lib.c (seq_build_list_pend): New static function.
This individually adds all items from the input
list, until it hits a terminating atom. If the
atom isn't nil, it converts the seq_build_t object
to improper operations.
(seq_build_improper_add, seq_build_improper_pend):
New static functions. These throw an error:
adding anything to an improper list is impossible.
(seq_build_improper_finish): New function, which
does nothing: the improper list is finished already.
(sb_list_ops): Use the seq_build_list_pend operation
rather than the generic one.
(sb_improper_ops): New static structure.
(seq_build_convert_to_improper): New static function.
Finishes the list, giving it the specified terminating
atom, and then switches to sb_improper_ops so that
adding is no longer possible.
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (tuples_func): Replace list accumulation
with make_like with seq_build.
* tests/012/seq.tl: Fix one test case here which no
longer errors out. It produces a tuple which is not
a string, due to the inclusion of a non-character
object.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|