summaryrefslogtreecommitdiffstats
path: root/tests
Commit message (Collapse)AuthorAgeFilesLines
* awk: tests for fconv.Kaz Kylheku2020-12-312-0/+21
| | | | | * tests/015/awk-fconv.tl, * tests/015/awk-fconv.expected: New files.
* chmod: disable some chmod tests on Cygwin.Kaz Kylheku2020-12-241-21/+26
| | | | | | | * tests/018/chmod.tl: Certain chmod test cases no longer work on Cygwin. The issue is the chmod system call. It produces completely nonsensical results in some cases. We disable these test cases on Cygwin.
* android: fix socket module, failing tests.Kaz Kylheku2020-12-234-15/+17
| | | | | | | | | | | | | * socket.c: Add missing #include <netinet/in.h>. * tests/017/glob-carray.tl, tests/017/glob-zarray.tl: Use same definition for struct glob as Cygwin. Both are of BSD origin. * tests/017/realpath.tl: Do not test on Android. * tests/common.tl (os-symbol): Detect Android and return :android. (libc): Handle :android.
* random: add tests validating WELL512a.Kaz Kylheku2020-10-072-0/+24
| | | | | | * tests/013/well512a.tl: New file. * tests/013/well512a.expected: New file.
* random: bugfix: incorrect WELL512a.Kaz Kylheku2020-10-071-59/+59
| | | | | | | | | | | | | | | | | | | * rand.c (rand32_bug): New static function formed by renaming the original buggy rand32. (rand32_good): Copy of rand32 with two bugfixes. The term involving variable r2 must be only left shifted by 28 bits, and not xor-ed with the original value. The order of operations is wrong in the term that contains the & operation. (rand32): New static function pointer variable, serving as the rand32 function. Points to rand32_good by default. (rand_compat_fixup): Test for 243 or lower compatibility, under which rand32 is made point to rand32_bug. This is done before the call to make_random_state for replacing *random-state*, which has to use the old function. * txr.1: compat note added. * tests/013/maze.expected: Updated.
* New functions trim-left and trim-right.Kaz Kylheku2020-10-052-0/+41
| | | | | | | | | * regex.c (trim_left, trim_right): New static functions. (regex_init): New intrinsics registered. * tests/015/trim.tl, tests/015/trim.expected: New files. * txr.1: Documented.
* oop: add tests for diamond problem.Kaz Kylheku2020-09-012-2/+23
| | | | | | | | * tests/012/oop-mi.tl (grand, base1, base2): Add list slot li to grand, targeted by :init and :fini handlers in all three structs. Added test case which triggers finalization. * tests/012/oop-mi.expected: Updated.
* New inaddr-str and in6addr-str functions.Kaz Kylheku2020-07-244-0/+198
| | | | | | | | | | | | | | | | | * lisplib.c (sock_set_entries): Register autoload entries for inaddr-str and in6addr-str. Register prefix symbol to be interned. * share/txr/stdlib/socket.tl (sockaddr-in, sockaddr-in6): Both structs get a new member, prefix, defaulting to the respective number of bits in the address. (inaddr-str, in6addr-str): New functions. * tests/014/iaddr-str, tests/014/inaddr-str.expected, tests/014/in6addr-str.tl, tests/014/in6addr-str.expected: New files * txr.1: Documented.
* New: protocol for iteration with structs.Kaz Kylheku2020-07-072-0/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (seq_iterable): Return t if argument is a structure supporting the iter-begin method. (seq_iter_get_oop, seq_iter_peek_oop, seq_iter_get_fast_oop, seq_iter_peek_fast_oop): New static functions. (seq_iter_init_with_info): Handle COBJ case. If the COBJ is a structure which suports the iter-begin method, then retrieve the iterator object by calling it, and then prepare the iterator structure for either the fast or the canonical protocol based on whether the iterator supports iter-more. (seq_iter_mark): Mark the iter member if the iterator is a struct object. (iter_begin): Rearrange tests here to check object type first before sequence kind. If the object is a structure supporting the iter-begin method, then call it and return its value. (iter_more, iter_step): Check for struct object with corresponding special methods and return. (iter_reset): Similar change like in iter_begin. We check for the iter-reset special method and try to use it, otherwise fall back on the regular iter_begin logic. * lib.h (struct seq_iter): New member next of the ul union for caching the result of a peek operation. * struct.c (iter_begin_s, iter_more_s, iter_item_s, iter_step_s, iter_reset_s): New symbol variables; (special_sym): Pointers to new symbol variables added to array. (struct_init): New symbol variables initialized. (get_special_required_slot): New function. * struct.h (iter_begin_s, iter_more_s, iter_item_s, iter_step_s, iter_reset_s): Declared. (enum special_slot): New enum members iter_begin_m, iter_more_m, iter_item_m, iter_step_m, iter_reset_m. (get_special_required_slot): Declared. * txr.1: Documented. * tests/012/oop-seq.expected: New file. * tests/012/oop-seq.tl: New file.
* lib: sort becomes non-destructive; nsort introduced.Kaz Kylheku2020-05-131-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I'm fixing a historic mistake copied from ANSI Lisp, which trips up language newcomers and sometimes even experienced users. The function innocently named sort will now return newly allocated structure. The function previously called sort will be available as nsort (non-consing/allocating sort). The shuffle function also becomes pure, and is accompanied by nshuffle. * eval (me_op): Continue to use destructive sort in this legacy code that is only triggered in very old compat mode. (eval_init): Registered nsort and nshuffle. * lib.c (nsort, nshuffle): New functions introduced, closely based on sort and shuffle. (sort, shuffle): Rewritten to avoid destructive behavior: work by copying the input and calling destructive counterparts. (sort_group): Continue to use destructive sort, which is safe; the structure is locally allocated. The sort_group function has pure semantics. (grade): Likewise. * lib.h (nsort, nshuffle): Declared. * share/txr/stdlib/getopts.tl (opthelp): Replace an instance of the (sort (copy-list ...)) pattern with just (sort ...). * tags.tl (toplevel): Continue to use destructive sort to sort tags before writing the tag file; the lifetime of the tags list ends when the file is written. * tests/010/seq.txr: Switch some sort calls to nsort to keep test case working. * txr.1: Documented.
* ifa: fix broken/invalid test case.Kaz Kylheku2020-04-232-4/+7
| | | | | | | | | | | | | | | | | | * tests/012/ifa.tl: The "ambiguous" test case is not ambiguous at all. The reason it was yielding :error previously was not due to the ifa macro identifying an ambiguity but due to the funcion < not accepting nil arguments. Since < now does accept nil arguments, this test broke. Fixing this test, and adding one that tests for the ambiguous case: multiple it-candidates being rejected by ifa at expansion time. * tests/common.tl (vtest): This macro requires maintenance. To test for expansion-time failure, we must use expand, not just macroexpand. In this case, the (ifa ...) macro call is wrapped in a (let ...) so macroexpand won't do it. Secondly, the expected value is an quote expression that must be evaluated if we need its value in vtest itself. Otherwise it won't compare equal to :error, since it is actually (quote :error).
* New function: assq and rassq.Kaz Kyheku2020-02-242-0/+8
| | | | | | | | | | | | | | | | | | | | | TXR Lisp is henceforth a dialect in which (cdr (assq key a-list)) works exactly as shown, without substitution of assql or assoc. * eval.c (eval_init): Register assq and rassq intrinsics. * lib.c (assq, rassq): New functions. * lib.h (assq, rassq): Declared. * txr.1: Documented. * tests/012/ashwin.tl: New file. * tests/012/ashwin.expected: New file.
* chmod tests: avoid sticky bit when not available.Kaz Kylheku2020-02-101-18/+25
| | | | | | | | | | | | | On Solaris, we can't set the sticky bit on a non-directory without special privilege. Let's detect whether we can set the sticky bit on our test object. If we can't, then we avoid executing tests that involve the sticky bit. * tests/018/chmod.tl (test-sticky): New variable. (cht): If test-sticky is false, only run the test if none of the inputs contain a 't'.
* chmod tests: use macro.Kaz Kylheku2020-02-101-3/+3
| | | | | | * tests/018/chmod.tl (mode-bits): Change body to correct quasiquote. (cht): Use previously unreferenced mode-bits macro.
* chmod: ugo perms sees effects from same clause.Kaz Kylheku2020-02-081-0/+1
| | | | | | | | | This is Coreutils chmod behavior. * sysif.c (chmod_wrap): Sample cmode into oldm at the start of every assigment before punching the masked hole into cmode. * tests/018/chmod.tl: Breaking test case added.
* chmod: ugo must refer to unaltered perms.Kaz Kylheku2020-02-081-0/+5
| | | | | | | | | | | | | | | | | | | Within the same clause, permissions given by ugo must refer to the unaltered permissions, before the target bits were masked out, otherwise self-assignment like o=o just clears the permissions. The other self-referential perm is X: it checks for existing x permissions. That works with the current value. * sysif.c (chmod_wrap): Keep the old permissions in a new loop variable called oldm. The u, g and o perms refer to oldm rather than to the updated value in cmode. When we hit a comma, we update oldm to the current value. The code for this is now in one place with a goto. * tests/018/chmod.tl: New test case that fails in the absence of this fix. Test cases confirming that X refers to the current permissions.
* chmod: bug handling comma after right hand ugo.Kaz Kylheku2020-02-071-0/+1
| | | | | | | | | | | | * sysif.c (chmod_wrap): The chm_comma state is transitioned to after seeing a right hand side u, g or o. These do not combine with other letters, so ch_comma expects a comma after which a new permission clause we start,. Therefore the srcm and who variables must be rest. It's also a good idea to continue the loop. * tests/018/chmod.tl: New test case which exposed the above issue.
* chmod: setuid/setgid bit bugfix and new tests.Kaz Kyheku2020-02-071-5/+6
| | | | | | | | | | | | | | | | | | * sysif.c (chmod_wrap): Again, related to the = operator, we must not punch a hole in the suid and sgid bits for all non-directory objects. This was based on a misinterpretation of some coreutils documentation, and doesn't match the actual behavior. Rather, if the owner is a target (including implicitly) then we mask out suid; and if the group owner is a targe, then we mask out sgid. Thus when we are doing a permission set not targetting the owner we don't touch suid, and similarly for the group owner and setgid. * tests/018/chmod.tl: Failed test diagnostics now identify which mode string was used. Some existing tests involving the suid/sgid bits have to be revised because this commit reflects a correction in the requirements. One new test is added.
* chmod: bugfix and new tests.Kaz Kyheku2020-02-071-0/+7
| | | | | | | | | | | | * sysif.c (chmod_wrap): When processing set (=), only punch a hole in the target permission area once per clause, so as not to clobber previously set modes. We do this by checking for the chm_perm state. Whenever '=' is processed, the state machine enters into that state; when any permission letter is then processed, it transitions out of that state. This gets the "u=rwsx" test to pass. * tests/018/chmod.tl: New tests.
* New tests for chmod.Kaz Kyheku2020-02-073-0/+45
| | | | | | | | | | | | | | | | The chmod fixes in the previous several commits were caught by this. * Makefile (tst/tests/018/chmod.ok): Set up TXR_ARGS for this test to give it the location of the temporary file to use as the object for testing permissions. (tst/tests/018): Disable TXR_DBG_OPTS for new directory. * tests/018/chmod.tl: New file. * tests/018/chmod.expected: Likewise. * tests/perm.tl: Likewise.
* ffi: fix broken char handling in undimensioned arrays.Kaz Kylheku2020-01-172-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | The undimensioned (array <type>) and (zarray <type>) types are not doing UTF-8 conversion when <type> is char or zchar, or doing what they are supposed to with the FFI character types, which is inconsistent from their dimensioned counterparts. * ffi.c (ffi_varray_dynsize): if the element type is marked for character conversion, then do the size calculation for char and zchar by measuring the UTF-8 coded size. (ffi_varray_alloc): Call ffi_varray_dynsize to get the size, to benefit from the char handling. Thus when FFI allocates buffers for a variable length array, it will allocate correct size required for the UTF-8 encoded string. (ffi_varray_put, ffi_varray_in): Here we must call ffi_varray_dynsize and divide by the element type to get the proper numer of elements. Then we must check for character conversion and handle the cases. (ffi_varray_null_term_in): Check for character conversion cases and route those through ffi_varray_in, which handles null-terminated strings. * tests/017/ffi-misc.tl: New file. * tests/017/ffi-misc.expected: New file.
* tests: broken glob test cases crash under musl.Kaz Kylheku2020-01-083-7/+21
| | | | | | | | | | | | | | | | | | | | | | Among several issues, the main one is that these test cases use the str-d FFI type for strings. This type means that TXR will take ownership of the memory; it creates the Lisp strings for the Lisp array, and then assuming that it has owership of the C strings, it will free them. On musl, this causes an instant crash, probably because the strings might not be individually coming from malloc. The only documented interface for freing glob resources is globfree; programs cannot assume that the strings can be freed. * tests/017/glob-carray.expected: Updated. * tests/017/glob-carray.tl (glob-t): Add missing flags member of type int. Change the array element string type from str-d to str. * tests/017/glob-zarray.tl: Likewise, and also add a comment to explain why we are not calling globfree in this test case.
* multiple-inheritance: test static-slot-home.Kaz Kylheku2019-12-132-1/+6
| | | | | | | * tests/012/oop-mi.tl: Add some coverage for static-slot-home function. * tests/012/oop-mi.expected: Updated.
* multiple-inheritance: super-method loose ends.Kaz Kylheku2019-12-132-4/+26
| | | | | | | | | | | | | | | | | * struct.c (do_super): New function. Now the common implementation for call_super_method, call_super_fun and super_method. (call_super_method, call_super_fun): Reduced to small wrappers around do_super. (super_method): Drill into the object to geet the struct_type handle, and then use do_super to get the method. * tests/012/oop-mi.tl: New tests for call-super-fun and call-super-method. * tests/012/oop-mi.expected: Updated. * txr.1: Updated.
* OOP: implementing multiple inheritance.Kaz Kylheku2019-12-112-0/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multiple inheritance is too useful to ignore any longer. * lib.c (subtypep): Perform subtypep calculation between two struct types via the new struct_subtype_p function. It's too complicated now to do with ad hoc code outside of struct.c. * share/txr/stdlib/struct.tl (defstruct): This macro now needs to deal with the super argument being possibly a list of base types instead of a single one. * strut.c (struct struct_type): Member super and super_handle are removed. New member nsupers, supers, and sus. (struct_init): The super function re-registered; it has an optional argument. (call_stinitfun_chain): The compat code here must now access the supertype differently. We don't bother dealing with multiple inheritance in the compat case; programs requesting compatibility with TXR 151 shoudn't be trying to use multiple inheritance. (get_struct_handles, count_super_stslots, get_super_slots, find_super_for_slot): New static functions, to off-load some new complexity from make_struct_type. (make_struct_type): Handle the increased complexity due to multiple inheritance. (super): Takes an additional argument now, to request which supertype to retrieve. Defaults to zero: the first one. (struct_type_destroy): Free the sus array. (struct_type_mark): Mark the supers slot. (call_initfun_chain): Call init functions of all bases, in right-to-left order. (call_postinitfun_chain): Likewise for postinit functions. (call_super_method, call_super_fun, super_method): Use the first base as the supertype. This requirement feels bad; it needs to be revisited. (do_struct_subtype_p): New static function. (struct_subtype_p): New function. (ancestor_with_static_slot): New static function. (method_name): Revised for multiple inheritance; now relies on ancestor_with_static_slot to find the original ancestor that has brought in a method, so we can use that type in the method name. * struct.h (super): Declaration updated. (struct_subtype_p): Declared. * tests/012/oop-mi.expected: New file. * tests/012/oop-mi.tl: New test cases. * txr.1: Revised in order to document multiple inheritance.
* bracket: bug: wrong result when function is applied.Kaz Kylheku2019-09-101-0/+14
| | | | | | | | | | | | Reported by user vapnik spaknik. * lib.c (bracket): Don't rely on the index variable to step through the arguments, because it only counts fixed arguments. The args_get function doesn't increment the index beyond args->fill; when popping arguments from args->list, index stays unmodified. * tests/016/arith.tl: Tests for bracket added.
* tests: add tests for list-builder and fix bug.Kaz Kylheku2019-09-101-0/+10
| | | | | | | * share/txr/stdlib/build.tl (list-buider pend*): Fix typo: apply should be append. Funny, this didn't propagate to ncon*. * tests/012/seq.tl: Some list-builder tests via build macro.
* tests: add tests for digits function.Kaz Kylheku2019-09-091-0/+18
| | | | * tests/016/arith.tl: Add various digits tests.
* New tests for sequence manipulation.Kaz Kylheku2019-09-092-0/+9
| | | | | | | | Just a few append cases with improper lists here to start with. * tests/012/seq.tl: New file. * tests/012/seq.expected: New file
* tests: add test related to recent @(collect) change.Kaz Kylheku2019-08-123-0/+33
| | | | | | | | | | | This test will misbehave on TXR without the previous fix; it will not collect columns of data which keep the corresponding rows items together. * tests/002/variant, tests/002/variant.expected, tests/002/variant.txr: New files. * Makefile (TXR_ARGS, TXR_OPTS): Override for new test.
* tests: add @{var1 var2} match test.Kaz Kylheku2019-07-034-4/+15
| | | | | | | | | | | | | | * tests/001/query-5.txr: New file. * tests/001/query-5.expected: New file. * Makefile (tst/tests/001/query-5.ok): Pass -B to txr for this new test. * tests/017/glob-carray.expected: Updated, because the glob test globs over the contents of tests/001 directory. * tests/017/glob-zarray.expected: Likewise.
* defset: bind new-val-sym to temporary variable.Kaz Kylheku2019-06-281-2/+12
| | | | | | | | | | | | | | | | | | | | | | Users of defset no longer have to ensure that in the store form, the symbol which gives the new value to be stored is inserted only once. * share/txr/stdlib/defset.tl (defset-expander): Transform the store form by inserting a temporary variable using alet. (sub-list, sub-vec, sub-str): These place forms no longer require a local gensym. * txr.1: Updated doc. * tests/012/defset.tl: The expected output for the inc case now incorporates a gensym that comes from the compiled defset macro. Since we can't control that by means of the gensym counter, we resort to extracting it from the expansion itself, then check the test case against a template which incorporates that gensym. We check that the extracted item really is a gensym: it's a symbol with no home package whose name starts with "g".
* defset: add tests.Kaz Kylheku2019-06-172-0/+11
| | | | | | * tests/012/defset.tl: New file. * tests/012/defset.expected: New file.
* u-d-arithmetic: proper treatment of ceil & round.Kaz Kylheku2019-03-301-2/+10
| | | | | | | | | | | | | | | * arith.c (r_ceil_s, r_round_s): New symbol variables. (ceildiv, roundiv): Route binary cases involving struts directly to binary methods so the object is responsible for the complete implementation. (arith_init): Initialize r_ceil_s and r_round_s. * tests/016/ud-arith.tl (numbase): Binary methods added for ceil and round. Test cases added. * txr.1: Descriptions for binary ceil and round methods added; Notes about non-existence of binary methods removed from unary ceil and round removed.
* Tests for user-defined arithmetic and fixes.Kaz Kylheku2019-03-302-0/+132
| | | | | | | | | | | | | | | | | | | | | | | * tests/016/ud-arith.expected b/tests/016/ud-arith.tl: New file. * tests/016/ud-arith.expected b/tests/016/ud-arith.expected: New file. * arith.c (divi): Bugfix: wrong argument tested for being a COBJ. (logtrunc): Fix incorrect method call: calling r-logtrunc-s for the object-in-left-position case. (sign_extend): Fix semantics not following documentation: dispatch method with original arguments. (divv): When there is just one argument, take advantage of the hitherto unused unary case of divi rather than giving it both arguments. The object dispatch is in that unary case, so we need it now. (arith_init): Fix wrong name of r_lognot_s symbol. * txr.1: Fix atan2 being documented as atan. Fix misspelling of r-lognot as lognot-r.
* The code expander becomes a public API.Kaz Kylheku2018-11-022-13/+13
| | | | | | | | | | | | | | | | | | | | | | | The functions sys:expand, sys:expand* and sys:expand-with-free-refs are now in the usr package and documented for public use. * eval.c (eval_init): Move registrations of the symbools expand, expand* and expand-with-free-refs from the system package to the user package. * share/txr/stdlib/awk.tl (sys:awk-mac-let, awk): Uses of sys:expand drop the sys: prefix. * share/txr/stdlib/op.tl (sys:op-alpha-rename): Likewise. * share/txr/stdlib/place.tl (call-upudate-expander, call-clobber-expander, call-delete-expander, sys:placelet-1): Likewise. * tests/011/macros-2.txr, tests/012/struct.tl: Likewise. * txr.1: Documented expand, expand* and expand-with-free-refs.
* tests: remove macro-time hack from man-or-boy test.Kaz Kylheku2018-07-171-1/+1
| | | | | | * tests/012/man-or-boy.tl (defun-cbn): We no longer need the macro-time expression here to force the evaluation of the defmacro form.
* hashing: overhaul part 1.Kaz Kylheku2018-07-041-45/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hashing of buffers and character strings is being replaced with a seedable hash, providing a tool against denial of service attacks against hash tables. This commit lays most of the groundwork: most of the internal interface changes, and a new hashing implementation. What is missing is the mechanisms to do the seeding. * hash.c (struct hash_ops): Hash operation now takes a seed argument of type ucnum. (struct hash): New member, seed. (hash_str_limit): Default value changed to INT_MAX. A short value opens the gateway to an obvious collision attack whereby strings sharing the same 128 character prefix are entered into the same hash table, which will defeat any seedings strategy. (randbox): New static array. Values come from the Kazlib hash module, but are not used in exactly the same way. (hash_c_str, hash_buf): Now take a seed argument, and are rewritten. (equal_hash): Takes a seed, and passes it to hash_c_str, hash_buf and to recursive self calls. (eql_hash_op): New static function. Adapts the eql_hash operation, which doesn't take a seed, to the new interface that calls for a seed. (obj_eq_hash_op): Take a seed; ignore it. (hash_hash_op): Take a seed, pass it down to equal_hash. (hash_eql_ops): Wire hash functiono pointer to eql_hash_op instead of eql_hash. (make_hash): For now, intialize the hash's seed to zero. (make_similar_hash): Copy original hash's seed. (gethash_c, gethash_e, remhash): Pass hash table's seed to the hashing function. (hash_equal): Pass a seed of zero to equal_hash for now; this function will soon acquire an optional parameter for the seed. * hash.h (equal_hash): Declaration updated. * lib.c (cobj_handle_hash_op): Take seed argument, pass down. * lib.h (cobj_ops): Hash operation now takes seed. (cobj_eq_hash_op, cobj_handle_hash_op): Declarations updated. * struct.c (struct_inst_hash): Take seed argument, pass down. * tests/009/json.expected: Updated, because the hash table included in this output is now printed in a different order.
* printer: improve object formatting.Kaz Kylheku2018-04-054-8/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is an issue with the printer in that it produces output whereby objects continue on the same line after a multi-line object, e.g: (foo (foobly bar xyzzy quux) (oops same line)) rather than: (foo (foobly bar xyzzy quux) (oops same line)) There is a simple fix for this: set a flag to force a line break on the next width-check operation whenever an object has been broken into multiple lines. width-check can return a Boolean indication whether it generated a line break, and so aggregate object printing routines can tell whether their object has been broken into lines, and set the flag. * stream.h (struct strm_base): New member, force_break. (force_break): Declared. * stream.c (strm_base_init): Extent initializer to cover force_break flag. (put_string, put_char): Clear the force_break flag whenever we hit column zero. (width_check): If indent mode is on, and force_break is true, generate a break. Clear force_break. (force_break): New function. (stream_init): Register force-break intrinsic. * buf.c (buf_print): Set the force break flag if the buffer was broken into multiple lines. * hash.c (hash_print_op): Set the force break flag if the hash was broken into multiple lines. * lib.c (obj_print_impl): Same logic for lists. * struct.c (struct_inst_print): Same logic for structs. * tests/009/json.expected, tests/011/macros-2.expected, tests/012/struct.tl, tests/017/glob-zarray.expected: Update expected textual output to reflect new formatting.
* eval: remove hack of macro deffers evaled on expansion.Kaz Kylheku2018-03-254-22/+25
| | | | | | | | | | | | | | | | | | * eval.c (do_expand): When a defmacro or defsymacro form is traversed, do not evaluate it, except in backward compatibility mode. Unfortunately, this breaks some code. * tests/011/macros-1.txr: A defmacro form has to be wrapped in macro-time. * tests/011/macros-2.txr: Likewise. * tests/011/mandel.txr: Likewise. * tests/012/man-or-boy.tl (defun-cbn): This macro generates a progn which which expects that a defmacro form will come into effect for the subsequent lambda in the same form. We must wrap it in macro-time to make this happen now.
* sub and replace redirect to structure methods.Kaz Kylheku2018-01-011-1/+4
| | | | | | | | | | | | | * lib.c (replace_obj): New static function. (sub): Handle struct case via lambda method. (replace): Handle struct case via replace_obj. * txr.1: Documented. * tests/012/aseq.tl (add): The lambda method now has to handle a range argument. One test case uses the last function, which for non-lists relies on sub, which now calls the lambda method if the object has one.
* hash: read/print consistency regression.Kaz Kylheku2017-12-281-48/+44
| | | | | | | | | | | | | | | | | | | | | | TXR 188 makes a slight mess of the #H notation. An :eql-based hash table prints as #H(() ...), but when that notation is read, it produces an :equal-based hash table. No aspect of this situation was intended; the intent was that the notation stays the same as before, and just the hash function changes to make :equal-based the default. Let's just go with this and have #H(() ...) denote :equal-based tables. * hash.c (hash_print_op): Print an :eql-based for eql-based hash tables, and nothing for equal-based ones. In compatibility mode with 188 and older, reproduce the old behavior, rendering equal-based tables with :equal-based and the absence of a symbol for eql-based. * txr.1: Updated places that touch on :equal-based and added compatibility notes. * tests/009/json.expected: updated, since equal-based hash tables now print without :equal-based keyword.
* macros: expand declined form in outer env.Kaz Kylheku2017-11-242-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch implements a new requirement which clarifies what happens when a macro declines to expand a form. To decline expanding a form means to return the original form (same object) without returning it. The expander detects this situation with an eq comparison on the input and output. The current behavior is that no further attempts are made to expand the form. This is problematic for various reasons. In code which is expanded more than once, this can lead to the expansion being different between the expansion passes. In the first pass, a local macro M might decline to expand a form. In the second pass, the local macro definition no longer exists, and the form does get expanded by a global macro M. This kind of instability introduces a flaw into complex macros which expand their argument material more than once. The new requirement is that if a macro definition declines to expand a macro, then a search takes place through the outer lexical scopes, and global scope, for the innermost macro definition which will expand the form. The search tries every macro in turn, stopping if a macro is found which doesn't decline the expansion, or after passing the global scope. * eval.c (expand_macro): Implement new searching behavior. * txr.1: Documented the expansion declining mechanism under defmacro and macrolet. * tests/011/macros-3.tl: New file. * tests/011/macros-3.expected: New file.
* awk: implement ranges right using functions.Kaz Kylheku2017-10-291-13/+13
| | | | | | | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk%--rng, sys:awk%--rng-, sys:awk%rng+, sys:awk%-rng+, sys:awk%--rng+): New functions. (sys:awk-mac-let): Rewritten range expander. The four basic ranges rng, rng-, -rng and -rng- are handled with in-line expansion, because by doing that we avoid unnecessarily evaluating the from-expression. The remaining cases expand to function calls to the new functions, which receive the flag vector, the index position in that vector and the values of the from and to expressions. The behavior change is that that the -- forms now do the right thing: they hide all leading records that satisfy the from-expression, right to the last record of the range if necessary. * tests/015/awk-rng.expected: Updated. * txr.1: Revise semantic description the -- range types, plus minor fixes.
* awk: more range test cases.Kaz Kylheku2017-10-272-1/+7
| | | | | | * tests/015/awk-rng.tl: More rows of data. * tests/015/awk-rng.expected: Updated.
* awk: five new range operators.Kaz Kylheku2017-10-252-0/+43
| | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys;awk-mac-let): Provide the implementation for the local macros --rng, --rng-, rng+, -rng+ and --rng+. * tests/015/awk-rng.tl: New file. * tests/015/awk-rng.expected: New file. * txr.1: Documented.
* tests: add lambda quine tests.Kaz Kylheku2017-07-072-0/+17
| | | | | | | | The tests fail as of this commit. * tests/012/quine.expected: New file. * tests/012/quine.tl: New file.
* structs: new tests for static-slot-ensure.Kaz Kylheku2017-07-052-0/+23
| | | | | | * tests/012/stslot.expected: New file. * tests/012/stslot.tl: New file. b/tests/012/stslot.tl
* Support ref, refset on structs via lambda, lambda-set.Kaz Kylheku2017-06-161-1/+1
| | | | | | | | | | | * lib.c (ref, refset): Check for lambda and lambda-set, respectively, and use it. * txr.1: Documented. * tests/012/aseq.tl (add lambda): Fix previously unused broken method which now causes test to go into infinite recursion.
* ffi: glob test: struct size on Linux and Cygwin.Kaz Kylheku2017-05-212-22/+40
| | | | | | | | | * tests/017/glob-carray.tl (glob-t): Restructure to case statement. Add padding to struct based on looking at the glibc definition. Add FFI definition based on Cygwin header. * tests/017/glob-zarray.tl (glob-t): Likewise.