| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_bit): New function.
(buf_init): Register buf_bit intrinsic.
* buf.h (buf_bit): Declared.
* tests/012/buf.h: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_bitset): New function.
(buf_init): Register buf-bitset intrinsic.
* buf.h (buf_bitset): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_not, buf_trunc): New functions.
(buf_init): Register buf-not and buf-trunc intrinsics.
* buf.h (buf_not, buf_trunc): Declared.
* tests/012/buf.h: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_and, buf_or, buf_xor): New functions.
(buf_init): buf-and, buf-or and buf-xor intrinsics registered.
* buf.h (buf_and, buf_or, buf_xor): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_fash): New function.
(buf_init): buf-fash intrinsic registered.
* buf.h (buf_fash): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (err_oflow): New static function.
(buf_compress): Use err_oflow.
(buf_ash): New function.
(buf_init): Register buf-ash intrinsic.
* buf.h (buf_ash): Declared.
* tests/012/buf.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_put_buf): Fix incorrect argument order, contrary
to documentation and inconsistent with other buf-put-* functions.
(compat_buf_put_buf): New static function. Detects wrong
argument order and swaps.
(buf_init): Register buf-put-buf intrinsic to new
static function. Thus buf-put-buf conforms to the documentation,
but also works if called with the incorect old argument order.
* test/012/buf.tl: New tests.
* txr.1: Documentation added to clarify behaviors when put
operation is out of the range of the destination buffer.
|
|
|
|
|
|
|
|
|
| |
* eval.c (do_progf, progf): New static functions.
(eva_init): Register progf intrinsic.
* tests/012/callable.tl: New test.
* txr.1: Documented.
|
|
|
|
|
| |
* tests/012/infix.tl (fft): express loop condition
more succinctly as a relational compound.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit extends infix with a post-processing step
applied to the output of parse-infix which improves
the code, and also implements math-like semantics for
relational operators, which I'm calling superfix.
Improving the code means that expressions like a + b + c,
which turn into (+ (+ a b) c) are cleaned up into
(+ a b c). This is done for all n-ary operators.
superfix means that clumps of certain operators
behave as a compound. For instance a < b <= c
means (and (< a b) (<= b c)), where b is evaluated
only once.
Some relational operators are n-ary; for those we
generate the n-ary expression, so that
a = b = c < d becomes (and (= a b c) (< c d)).
* stdlib/infix.tl (*ifx-env*): New special variable.
We use this for communicating the macro environment
down into the new finish-infix function, without
having to pass a parameter through all the recursion.
(eq, eql, equal, neq, neql, nequal, /=, <, >, <=, >=,
less, greater, lequal, gequal): These operators
become right associative, and are merged into a single
precedence level.
(finish-infix): New function which coalesces compounds
of n-ary operations and converts the postfix chains
of relational operators into the correct translation
of superfix semantics.
(infix-expand-hook): Call finish-infix on the output
of parse-infix, taking care to bind the *ifx-env*
variable to the environment we are given.
* tests/012/infix.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* test/012/infix.tl: New tests.
(*compiling*) New variable.
(unless-compiling): New macro.
One :error test elicits a warning during the compiled version
of the test that is hard to squelch, so we just remove
it from the compiled test case.
(fft): Remove unused variable i; all for loops locally bind i.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (detect-infix): Redesign.
New algorithm looks only at the first two or three
elements. Arguments that are not operators are
only considered operands if they don't have
function bindings. This is important because sometimes
the logic is applied to the arguments in a DWIM
bracket form, like [apply / args], which we don't
want to treat as (/ apply args).
* tests/012/infix.tl: New test.
* txr.1: Redocumented.
|
|
|
|
|
|
|
|
| |
* tests/012/infix.tl: New tests providing some coverage
of ifx, and its phony infix also. Big test case with
FFT function.
* tests/common.tl (msstest): New macro.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (hmac_set_entries, hmac_instantiate): New static
functions.
(autoload_init): Register autoload of hmac module.
* stdlib/hmac.tl: New file.
* tests/013/chksum.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* chksum.c (sha1_stream_read, sha256_stream_read,
md5_stream_read): New static function.
(sha1_stream_impl, sha256_stream_impl, md5_stream_impl):
Logic moved into new functions.
(sha1, sha256, md5): Support stream argument, via corresponding
stream_impl function, passing nil as the size to snarf the
whole stream. This could have been implemented without
the above refactoring. In other words, the _stream functions
only need to be used now when a limit on the number of
bytes must be specified.
(sha1_hash, sha256_hash, md5_hash): Support a stream
argument.
* gencksum.txr: All above chksum.c changes actually
generated from here.
* tests/013/chksum.tl: New tests.
* txr.1: Documentation updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/infix.tl (parse-infix): Change how we treat fn (arg ...)
and elem [arg ...] forms. These now translate to (fn (arg ...))
and [elem (arg ...)] rather than (fn arg ...) and [elem arg ...].
(detect-infix): detect certain op [arg ...] forms as infix.
(infix-expand-hook): Revise detection logic to handle bracket
expression forms, and parenthesized single terms.
The latter are needed to reduce [elem (atom)] to [elem atom].
* tests/012/infix.tl: Fix up some tests.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* tests/012/infix.tl (quadractic-roots): New function.
Add couple of tests.
* txr.1: Add quadratic-roots as example to ifx macro.
|
|
|
|
|
|
| |
* tests/012/infix.tl: New file.
* tests/012/compile.tl: Add infix to compiled tests.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Here we fix bugs in expand-hook-combine, imrprove the tests
and make different recommendations in the manual about hook
order.
* eval.c (expand_hook_combine_fun): Fix incorrect tests
which cause the next function to be ignored.
* tests/011/exphook.tl: (pico-style-expand-hook): Needs tweak
to evaluate constantp using standard expansion (without
pico-style), so that pico-style can nest with ifx in either
order.
(pico-style): Now when we call expand-hook-combine
we give the new hook first, and the existing one next.
This behavior makes more sense as a default go-to strategy
because it gives priority to the innermost hook-based macro,
closest to the code.
(infix-expand-hook, ifx): Add test cases which test nesting of
hook-based macros.
* txr.1: Opposite recommendation made about chaining of
expand hooks: new first, fall back on old.
Example adjusted.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function provides a functional combinator that takes
the responsibility of combining expand hooks.
* eval.c (expand_hook_combine_fun, expand_hook_combine):
New static functions.
(eval_init): Register expand-hook-combine intrinsic.
* tests/011/exphook.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autolod.c (match_set_entries): Autoload match module on
match-tuple-case.
* match.tl (match-tuple-case): New macro.
* tests/011/patmatch.tl: New tests.
The macro is trivial; if lambda-match works, the
macro works.
* 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 rand function always calls rand32 at least one for
each call, even for small moduli that need only a few
pseudo-random bits. For instance when the modulus
is 2, the function requires only one pseudo-random
bit from the PRNG, yet it takes 32 and throws away 31.
With this commit, that changes. For moduli of 65536
or smaller, the bits are used more efficiently;
and for a modulus of 2, the function can satisfy
32 calls using the bits of a single rand32_t word:
one stepping of the WELL512a PRNG.
* rand.c (struct rand_state): New member, shift. Holds the
shift register for rand/random to take bits from, replenished
from rand32() when it runs out. The shift register detects
when it runs out of bits in a clever way, without any
additional variable. The register is regarded as being
33 bits wide, with a top bit that is always 1. When
the register is empty, a 32 bit word is taken from the
PRNG. The required random bits are taken from the word, and
it is then shifted to the right. (We take only power-of-two
amounts out of the shift register: 1, 2, 4, 8 or 16 bits).
Even the smallest shift produces enough room that the
33rd bit can be added to the word, into its shifted position.
After that, the shift register is considered to have enough
bits for a given modulus if its value is less than equal
to the mask. I.e if we were to take bits from it, we would
be including the unconditional signaling bit. At that
point we clobber the shift register with a new set of 32 bits
from the PRNG, take the random bits we need, shift it to
the right and add the signaling bit.
(opt_noshift): New static variable; indicates whether
we are in compatibility mode, requiring the shift register
optimization to be defeated.
(make_random_state): Initialize shift register to 0
in several places.
(random): Implement various small modulus cases. There are
specific cases for moduli that are exactly 65536, 256, 16, 4,
3 and 2. The in-between cases are handled by shifting the
bits in the same amounts as the next higher power of two from
this list of sizes: 16, 8, or 4 bits. For these cases, we
calculate the smallest Mersenne modulus which covers the bits
of the actual moduls and use that for rejecting potential
values, just as we do in the general large modulus case. For
instance if the modulus is 60 (range 0 to 59), that lands into
the 8 bit shift range: we pull 8 bits at a time from the shift
register. But the modulus 60 is covered by the six bit mask
63. We mask each 8 bit value with 63, and if it is in the
required range 0 to 59, we accept it, otherwise draw
another 8 bits.
(rand_compat_fixup): Initialize opt_noshift to 1 if
the requested compat version is 299 or less.
* tests/012/sort.tl: Fix one test case involving shuffled
data. The shufle function uses rand with small moduli,
so its behavior changes for the same PRNG sequence.
* tests/013/maze.expected: Likewise, the generated
pseudo-random maze in the maze test case is different now;
we must update to the new expected output.
* txr.1: Document that a value of 299 or less of the
compatibility -C option has an effect on rand.
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_letrec): New function.
(eval_init): Register letrec intrinsic macro.
* tests/012/let.tl: New file.
* txr.1: Documented, and also referenced from mlet.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (glob_set_entries): Remove autoload on
sys:brace-expand. Add usr:exp.
* stdlib/glob.tl (brace-expand): Renamed to usr:bexp.
(glob*): Call bexp rather than brace-expand.
* tests/018/glob.tl: Rename references to sys:brace
expand to bexp.
* txr.1: Add section describing the bexp function.
Move brace expansion documentation from glob* to this
new section, adjusting the wording a little bit, mainly
to avoid referring to "patterns". Point glob* documentation
to bexp, which also in turn references glob*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlb/glob.tl (bexp-parse): Recognize .. as a token.
(bexp-parse-brace): If a brace expansion doesn't contain
commas, then check whether it contains .. and that its elements
are all strings. In that case it is a possible range expansion
and we thus transform it to a (- ...) node, subject to
more validation in bexp-expand.
(bexp-expand): Add casees to handle range expansion,
taking care that invalid forms translate to verbatim
syntax.
* tests/018/glob.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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (iter_more): Do not return t for unrecognized
objects, but thrown an exception. Do return t for
conses, which is necessary since they are iterators
for lists. Also, as a special case, we return t for
struct objects that don't have an iter-more method.
This is needed for the documented fast protocol.
Iterator objects implementing the fast protocol
still get iter-more invoked on them. The client
usually doesn't know that the iterator implements
the fast protocol, and so calls iter-more, which
unconditionally has to returns true.
(iter_item): Do not fall back on car(iter) for all
unhandled objects. Only conses are handled
via car. All unrecognized objects trigger an
exception.
(iter_step): Do not try to handle list-like
objects via cdr, only lists.
Improve the diagnostic for hitting the end of
an improper list: diagnostic shows the cons
cell rather than just the terminating atom.
* tests/012/iter.tl: Some test cases validating
that the functions error out for strings and
vectors. Much more coverage is possible here but
doesn't seem worth it; e.g. that the functions
reject a buffer, regex, function, ...
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/awk (awk-state upd-rec-to-f): Handle a new case
of fs being the keyword symbol :csv, producing a
field-splitting lambda that calls get-csv.
* tests/015/awk-basic.tl: Several new test cases for
this CSV feature.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Handle field separations with lambdas, similarly to record
separation. The idea is that we replace the rec-to-f method,
which contains a cond statement checking the variables for
which field separation discipline applies, with a lambda which
is updated whenever any of those ariables change.
* awk.tl (awk-state): New instance slot, rec-to-f.
(awk-state :postinit): Call new upd-rec-to-f method
so that rec-to-f is populated with the default field
separating lambda.
(awk-state rec-to-f): Method removed.
(awk-state upd-rec-to-f): New method, based on rec-to-f.
This doesn't perform the field separation, but returns
a lambda which will perform it.
(awk-state loop): We must call upd-rec-to-f whenever
we change par-mode, because it influences field separation.
(awk-mac-let): Replace the symbol macros fs, ft, fw and
kfs with new implementations that use the reactive slot
mechanism provided by rslot. Whenever the awk macro assigns
any of these, the upd-rec-to-f method will be called.
* tests/015/awk-basic.tl: New file. These basic tests of
field separation pass before and after this change.
* tests/common.tl (otest, motest): New macros.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (get_csv): Let's add a new state init. If get_char
returns nil and we are in the init state, let's bail to a
nil return. While we are at it, let's not allocate the record
or string until we read at least one character. If we read
a character in the init state, let's allocate those two
objects, and then change to the rfield state and fall through
to it to handle the character.
* tests/010/csv.tl: Fix one incorrect test: (tocsv "") now
returns nil, as it should. Add tests for multiple record
extraction, also covering missing line termination on the last
record as well as CR-LF termination.
* txr.1: Documented nil return conditions.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (put_csv, tocsv): New functions.
(stream_init): put-csv and tocsv intrinsics registered.
* stream.h (put_csv, tocsv): Declared.
* tests/010/csv.tl (mtest-pcsv): New macro.
New test cases.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autloload.c (csv_set_entries, csv_instantiate): New
static funtions.
(autoload_init): Register autoload of stdlib/csv
module via new functions.
* stdlib/csv.tl: New file.
* tests/010/csv.tl: Likewise.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (enum_set_entries, enum_instantiate): New static
functions.
(autoload_init): Register autoload of stdlib/enum module
via new functions.
* stdlib/enum.tl: New file.
* tests/016/enum.tl: Likewise.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (op_set_entries): Autoload on lop1 symbol.
* stldlib/op.tl (sys:op-expand): Add lop1 case.
(sys:opip-expand): Add lop1 to the list of operators
that are recgonized and specially treated.
(lop1): New macro.
* tests/012/op.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.h (struct json_opts): Member flat removed.
I noticed that !jo.flat was always being tested together
with jo.fmt == json_fmt_standard. Except for a few
places where the code only tested for json_fmt_standard,
resulting in flat output, but some extra spaces.
What distiguishes flat mode now is simply that we
disable stream indentation.
* lib.c (out_json_rec): Remove tests for !jo.flat.
(out_json): Remove initialization of jo.flat member.
In this function we set up indentation on the stream
resulting in multi-line mode (existing behavior).
(put_json): Remove initialization of jo.flat member.
If flat mode is requested, then it overrides the
format to json_fmt_default. I.e. json_fmt_standard
coresponding to :standard is only in effect if flat
is not requested.
In this function we set up indentation on the stream
if flat mode isn't requested, otherwise we disable
indentation (existing behavior, enough to make flat
work).
* tests/010/json.tl: Tests for flat mode, :standard
formatting, and combinaton of both.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The lop macro is inconsistent from op in that it
inserts the trailing function arguments on the
left even if arguments are explicitly given in the
form via @1, @2, ... or @rest. This change makes
lop is equivalent to op in all situations when these
metas are given.
* stdlib/op.tl (compat-225, compat-298): New top-level
variables.
(op-expand): local variable compat replaced by references to
compat-225. If compat-298 is *not* in effect, then metas
are checked for first in the cond, preventing the lop
transformation from taking place.
* tests/012/op.tl: Test cases for lop, combinations of
do with lop and a few for op also.
* txr.1: Redocumented, added compat notes.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/match.tl (match-case-to-casequal): the (do inc
dfl-cnt) action has a problem: it inserts an implicit extra
parameter to the invocation of inc, which crashes the +
addition due to that parameter being the matching @nil object.
We don't need this entire case because it handles @nil,
which also matches the following case for (sys:var ...),
since @nil is (sys:var nil). That case ahs the same action
of incrementing dfl-cnt.
* tests/011/patmatch.tl: Test case added.
|
|
|
|
|
|
|
|
|
| |
* lib.c (seq_iter_init_with_info): String ranges are
inclusive. We must not assume at a range whose endpoints are
the same is empty; we must check that case for the endpoints
being strings.
* tests/012/seq.tl: New tests.
|
|
|
|
| |
* tests/012/seq.tl: New tests.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Ranges are iterable, denoting abstract sequences. The copy
function now copies a range by constructing the array.
This is useful when copy is used for the purpose of obtaining
a mutable copy. For example, (shuffle 0..100) will now work,
returning a shuffled vector of the integers from 0 to 99.
* lib.c (copy): Handle RNG case via vec_seq.
* tests/012/seq.tl,
* tests/012/sort.tl: New test cases.
* txr.1: Documented. Documentation for the copy function
improved.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit e7ce1b7d7da3fdebee6d5ba67f359bc6e3bb9e52
broke things.
This fix affects the function read-until-match,
scan-until-match and count-until-match which share
implementation.
* regex.c (scan_until_common): In the REGM_MATCH_DONE
and REGM_MATCH cases, we must push the character onto
the local stack, before doing the match = stack
assignment. Otherwise, it's possible that the stack
is empty and so no match is recorded. The REGM_FAIL
case will then behave as if no match was found, consuming
a character and continuing.
* txr.1: Codify an existing behavior: only non-empty matches
for the regex are considered by read-until-match.
* tests/015/regex.tl: New file. I am amazed to discover
that we don't seem to have a test suite for regexes at all.
Putting the tests here which confirm this fix and provide
coverage for some edge cases in read-until-match.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 (make_like): Simplify implementation using seq_build,
which also lets it handle more cases.
* tests/012/seq.tl: New tests. Some existing test fixed,
including one for tuples*.
* txr.1: Documentation updated: mainly that make-like
doesn't strictly require a list argument.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (zip_fun): Renamed to seq_like.
(zipv): Follow rename of zip_fun.
(eval_init): Register seq-like intrinsic.
* tests/seq.tl: Some tests for make-like and seq-like,
revealing a difference: make-like needs to be
rewritten to use seq_build.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.h (struct parser): New member, read_json_int.
* parser.c (read_json_int_s): New symbol variable
for *read-json-int* symbol.
(parser_common_init): Look up value of *read-json-int*
and store in read_json_int struct member.
(parse_init): Initialize read_json_int_s with interned
symbol and also register the dynamic variable.
* parser.l (grammar): Extend the {JNUM} rule to check
the read_json_int flag and produce an integer value if
the lexeme does not contain a decimal point, e or E.
* tests/010/json.tl: New tests.
* txr.1: Documented.
* lex.yy.c.shipped: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* struct.h (slotset_s, static_slot_s, static_slot_set_s): New
symbol variables declared.
(enum special_slot): New enum symbols: slot_m, slotset_m,
static_slot_m, static_slot_set_m.
* struct.c (slotset_s, static_slot_s, static_slot_set_s): New
symbol variables.
(special_sym): Associate new symbols with new enums.
(struct_init): Intern slotset, static-slot and static-slot-set
symbols, initializing the variables. Change the registrations
of the same-named functions to use the variables.
(slot, maybe_slot, slotset, static_slot, static_slot_set):
In the no-such-slot case, check for the special method and
call it.
* tests/012/oop.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|