summaryrefslogtreecommitdiffstats
path: root/tests/012
Commit message (Collapse)AuthorAgeFilesLines
* expander: handle format string in quasi.Kaz Kylheku2025-05-191-0/+6
| | | | | | | | * eval.c (expand_quasi): Quasiliteral sys:var items now have a format string, which we have to propagate to the expansion. * tests/012/quasi.tl: New tests.
* quasistrings: support format notation.Kaz Kylheku2025-05-181-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds support to quasiliterals to have the inserted items formatted via a format conversion specifier, for example @~3,3a:abc is @abc modified by ~3,3a format conversion. When the inserted value is a list, the conversion is distributed over the elements individually. Otherwise it applies to the entire item. * eval.c (fmt_tostring, fmt_cat): Take additional format string argument. If it isn't nil, then do the string conversion via the fmt1 function rather than tostring. (do_format_field): Take format string argument, and pass down to fmt_cat. (format_field); Take format string argument and pass down to do_format_field. (fmt_simple, fmt_flex): Pass nil format string argument to fmt_tostring. (fmt_simple_fmstr, fmt_flex_fmstr): New static functions, like fmt_simple and fmt_flex but with format string arg. Used as run-time support for compiler-generated quasilit code for cases when format conversion specifier is present. (subst_vars): Extract the new format string frome each variable item. Pass it down to fmt_tostring, format_field and fmt_cat. (eval_init): Register sys:fmt-simple-fmstr and sys:flex-fmstr intrinsics. * eval.h (format_field): Declaration updated. * lib.c (out_quasi_str_sym): Take format string argument. If it is present, output it after the @, followed by a colon, to reproduce the read notation. (out_quasi_str): Pass down the format string, taken from the fourth element of a sys:var item of the quasiliteral. For simple symbolic items, pass down nil. * match.c (tx_subst_vars): Pass nil as new argument of format_field. The output variables of the TXR Pattern language do not exhibit this feature. * parser.l (FMT): New pattern for matching the format string part. (grammar): The rule which recognizes @ in quasiliterals optionally scans the format notation, and turns it into a string attached to the token's semantic value, which is now of type val (see parser.y remarks). * parser.y (tokens): The '@' token's %type changed from lineno to val so it can carry the format string. (q_var): If format string is present in the @ symbol, then include it as the fourth element of the sys:var form. This rule handles braced items. (meta): We can no longer get the line number from the @ item, so we get it from n_expr. (quasi_item): Similar to q_var change here. This handles @ followed by unbraced items: symbols and other expressions. * stdlib/compiler.tl (expand-quasi-mods): Take format string argument. When the format string is present, then generate code which uses the new alternative run-time support functions, and passes them the format string as an argument. (expand-quasi-args): Extend the sys:var match to extract the format string if it is present. Pass it down to expand-quasi-mods. * stdlib/match.tl (expand-quasi-match): Add an error case diagnosing the situation when the program tries to use a format-conversion-endowed item in a quasilit pattern. * stream.[ch] (fmt1): New function. * tests/012/quasi.tl: New tests. * txr.1: Documented. * lex.yy.c.shipped, y.tab.c.shipped: Regenerated.
* infix: add missing ~ complement operator.Kaz Kylheku2025-05-161-0/+4
| | | | | | | | | * stdlib/infix.tl (toplevel): New ~ operator, prefix at level 35, tied to lognot function. * tests/012/infix.tl: New tests. * txr.1: Documented.
* buf: bug: empty fill pattern.Kaz Kylheku2025-05-161-0/+2
| | | | | | | | | | * buf.c (prepare_pattern): Do not return a zero length pattern for an empty buffer. Callers don't deal with this properly. Return a one byte pattern that is zero. * test/012/buf.tl: Test case added. * txr.1: Documented.
* buf: make-buf and buf-set-length take pattern.Kaz Kylheku2025-05-161-0/+31
| | | | | | | | | | | | | The init-val parameter of make-buf and buf-set-length is generalized to a possibly multi-byte fill pattern. * buf.c (make_buf, buf_do_set_len): Change init-val parameter to init-pat, and implement. We optimize the to memset when it's a one-byte pattern. * tests/012/buf.tl: New tests. * txr.1: Documented.
* syntax: allow for multiline qref chaining.Kaz Kylheku2025-05-151-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | Introducing a relaxation in the obj.slot.(method arg) syntax. There can be whitespace to the right of the dot, for splitting across multiple lines, as: obj. slot. (method arg) * parser.l (OREFDOT): Allow optional whitespace to the right of .? * parser.y (n_expr): Add a n_expr LAMBDOT n_expr phrase, with same semantic rule as n_expr '.' n_expr. We cannot add optional whitespace after . in the lexer because that is ambiguous with LAMBDOT. * tests/012/syntax.tl: New tewt cases. * txr.1: Documented. * lex.yy.c.shipped, y.tab.c.shipped: Regenerated.
* New string compression/decompression functions.Kaz Kylheku2025-05-151-1/+6
| | | | | | | | | | | | * 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.
* New function: buf-xor-pattern.Kaz Kylheku2025-05-111-0/+11
| | | | | | | | | | | | | | * 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.
* infix: bug: non-infix expressions conflated with infix.Kaz Kylheku2025-05-071-13/+13
| | | | | | | | | | | | | | | | | | | The problem is that (parse-infix '(x < y < z)) and (parse-infix '(x < (< y z)) produce exactly the same parse and will be treated the same way. But we would like (< y z) to be left alone. The fix is to annotate all compound terms such that finish-infix will not recurse into them. * stdlib/infix.tl (parse-infix): When an operand is seen that is a compound expression X it is turned into @X, in other words (sys:expr X). (finish-infix): Recognize (sys:expr X) and convert it into X without recursing into it. * tests/012/infix.tl: Update a number of test cases. * txr.1: Documented.
* New function: buf-binary-width.Kaz Kylheku2025-05-071-0/+56
| | | | | | | | | | | * buf.c (buf_binary_width): New function. (buf_init): Register buf-binary-width intrinsic. * buf.h (buf_binary_width): Declared. * tests/012/buf.tl: New tests. * txr.1: Documented.
* New function: buf-count-ones.Kaz Kylheku2025-05-061-0/+140
| | | | | | | | | | | * buf.c (buf_count_ones): New function. (buf_init): Register buf-count-ones intrinsic. * buf.h (buf_count_ones): Declared. * tests/012/buf.h: New tests. * txr.1: Documented.
* New function: buf-test.Kaz Kylheku2025-05-061-0/+24
| | | | | | | | | | | * buf.c (buf_test): New function. (buf_init): Register buf-test intrinsic. * buf.h (buf_test): Declared. * tests/012/buf.tl: New tests. * txr.1: Documented.
* New function: buf-zero-p.Kaz Kylheku2025-05-061-0/+22
| | | | | | | | | | | * buf.c (buf_zero_p): New function. (buf_init): Register buf-zero-p intrinsic. * buf.h (buf_zero_p): Declared. * tests/012/buf.tl: New tests. * txr.1: Documented.
* New function: buf-bit.Kaz Kylheku2025-05-051-0/+6
| | | | | | | | | | | * 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.
* New function: buf-bitset.Kaz Kylheku2025-05-051-0/+16
| | | | | | | | | | | * 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.
* New functions: buf-not and buf-trunc.Kaz Kylheku2025-05-051-0/+27
| | | | | | | | | | | * 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.
* New functions: buf-and, buf-or, buf-xor.Kaz Kylheku2025-05-051-0/+69
| | | | | | | | | | | * 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.
* New function: buf-fash.Kaz Kylheku2025-05-051-0/+63
| | | | | | | | | | | * 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.
* New function; buf-ash.Kaz Kylheku2025-05-051-0/+90
| | | | | | | | | | | | | * 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: buf-put-buf: wrong argument order.Kaz Kylheku2025-05-031-0/+25
| | | | | | | | | | | | | | | * 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.
* New function: progf.Kaz Kylheku2025-05-021-0/+5
| | | | | | | | | * eval.c (do_progf, progf): New static functions. (eva_init): Register progf intrinsic. * tests/012/callable.tl: New test. * txr.1: Documented.
* infix: use superfix in fft test case.Kaz Kylheku2025-05-021-1/+1
| | | | | * tests/012/infix.tl (fft): express loop condition more succinctly as a relational compound.
* infix: superfix relational operators; better code.Kaz Kylheku2025-05-011-0/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* infix: test cases for prefix phony.Kaz Kylheku2025-04-231-2/+19
| | | | | | | | | | * 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.
* infix: revise auto-detection algorithm.Kaz Kylheku2025-04-211-6/+6
| | | | | | | | | | | | | | | * 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.
* infix: more test cases.Kaz Kylheku2025-04-181-0/+57
| | | | | | | | * 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.
* infix: revise auto-detection and parsing.Kaz Kylheku2025-04-091-9/+9
| | | | | | | | | | | | | | * 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.
* infix: add quadratic-roots testKaz Kylheku2025-04-061-0/+10
| | | | | | | * tests/012/infix.tl (quadractic-roots): New function. Add couple of tests. * txr.1: Add quadratic-roots as example to ifx macro.
* infix: add tests.Kaz Kylheku2025-04-062-1/+68
| | | | | | * tests/012/infix.tl: New file. * tests/012/compile.tl: Add infix to compiled tests.
* New function: remove.Kaz Kylheku2025-03-271-0/+24
| | | | | | | | | | | | | | | 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.
* rand: use PRNG bits more economically for small moduli.Kaz Kylheku2025-03-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* New macro: letrec.Kaz Kylheku2025-03-211-0/+21
| | | | | | | | | * 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.
* New feature: range iteration with skip.Kaz Kylheku2025-03-071-0/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* New function: iterp.Kaz Kylheku2025-03-071-0/+20
| | | | | | | | | | | | | | | | | * 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.
* iterator API: reject objects that don't make sense.Kaz Kylheku2025-03-061-0/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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, ...
* New macro: lop1.Kaz Kylheku2025-01-171-0/+13
| | | | | | | | | | | | | * 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.
* lop: don't insert args when metas present.Kaz Kylheku2025-01-081-0/+44
| | | | | | | | | | | | | | | | | | | | | 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.
* string ranges: bug: ranges of length 1.Kaz Kylheku2024-12-151-0/+12
| | | | | | | | | * 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 for string range length.Kaz Kylheku2024-12-151-0/+12
| | | | * tests/012/seq.tl: New tests.
* copy: now handles range objects.Kaz Kylheku2024-10-012-0/+6
| | | | | | | | | | | | | | | | 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.
* keep-if, remove-if, keep-keys-if: mapfun argument.Kaz Kylheku2024-07-301-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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: more permissive implementation.Kaz Kylheku2024-07-241-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* make-like: use seq_build.Kaz Kylheku2024-07-231-3/+5
| | | | | | | | | | | * 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.
* New function: seq-like.Kaz Kylheku2024-07-231-0/+14
| | | | | | | | | | | | * 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.
* oop: special methods to handle missing slots.Kaz Kylheku2024-07-191-0/+36
| | | | | | | | | | | | | | | | | | | | | * 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.
* New functions: find-maxes and find-mins.Kaz Kylheku2024-07-161-0/+22
| | | | | | | | | | | * 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.
* New funtion related to where function.Kaz Kylheku2024-07-111-0/+39
| | | | | | | | | | | | | | * 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.
* partition, split, split*: bug handling negative indices.Kaz Kylheku2024-07-101-19/+31
| | | | | | | | | | | | | | | | * lib.c (partition_func, split_func, split_star_func): When negative indices occur after the sequence has already been shortened, the conversion to positivce must take into account the base. This must be added so that the positive index produced is relative to the original length of the input sequence. When index_rebased is calculated, the base is subtracted out again. If we based the positive index off the shortened length, it's as if we are subtracting base twice. * tests/012/seq.tl: Dubious test cases for split* are replaced with the new results that make sense. Additional test cases are added which cover this issue, for not only split* but split and partition.
* split, split*: fix poor behavior for beyond-length indices.Kaz Kylheku2024-07-101-24/+24
| | | | | | | | | | * lib.c (split_func, split_Star_func): Ignore indices greater than the length of the sequence, the same as negative indices are ignored which don't become nonnegative after adding the length. * tests/012/seq.tl: Fix questionable test cases, which now confirm the right behavior.
* partition: add negative index tests.Kaz Kylheku2024-07-101-0/+36
| | | | * tests/012/seq.tl: New tests.