summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* txr: bug in handling @{nil ...} variable match.Kaz Kylheku2023-12-173-1/+7
| | | | | | | | | | | | | | | | | | | | | | | In March 2012, b7f1f4c5bbea86e288b6a4d68595c1d2d07217bd introduced the feature that the @nil variable matches and discards. This was incompletely implemented. Some cases of a nil variable with modifiers fail to match. * match.c (dest_bind): This function must correctly handle the case when pattern is nil: it should just return bindings without extending them. If the pattern is any nonbindable symbol, it should indicate a failed match using t. The logic has not been touched since 2009, at which time an additional bogosity was introduced of calling funcall(testfun, pattern, value) when pattern is a non-bindable symbol. If value is a string, that could never work. Possibly the idea is that the value could come from a symbol-valued expression, such as one producing a keyword symbol. We are not going to support that, unless someone complains. * tests/000/nilvar.txr, tests/000/nilvar.expected: New files, providing a test case that fails without this commit.
* hash: small fix in function self name.Kaz Kylheku2023-12-111-1/+1
| | | | | * hash.c (gethash_d): Use gethash-d as self rather than gethash_d for consistency.
* listener: fix several bugs in auto compound expr mode.Kaz Kylheku2023-12-111-3/+5
| | | | | | | | | | | | * parser.c (repl): The first bug is that we are not correctly checking the special variable: auto_parens holds the binding. Thus TXR was behaving as if they feature is always enabled. The second bug is that forms might not be a list; it could be the colon symbol, so we cannot evaluate cdr(forms). The third bug is that we don't want to create (progn . :) when forms is the : symbol. These two bugs are reproduced by turning on the mode and evaluating (1 2 3 . 4 5 6), a bad form.
* compiler: handle non-locally-exiting top-level forms.Kaz Kylheku2023-12-111-1/+4
| | | | | | | | | | | | | | * stdlib/compiler.tl (compile-file-conditionally): When evaluation of a compiled top-level form is not suppressed, there is a risk that it can terminate non-locally, via throwing an exception or performing a block return. The compilation of the file is then aborted. We can do better: using an unwind-protect, we can catch all non-local control transfers out of the form and just ignore them. The motivation for this is that it lets us compile files which call (return-from load ...), without requiring that it be written as (compile-only (return-from load ...)). Other things will work, like compiling a (load "foo") where foo doesn't exist or aborts due to errors.
* load: load block value should be exit status.Kaz Kylheku2023-12-117-11/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When TXR executes a top-level program, such that it will exit when the last form in that program terminates, it simulates a load. There is a block named load visible, and the program can evaluate a (return-from load <expr>). The value of that <expr> is thrown away, and the termination status is always unsuccessful. In this patch, (return-from load <expr>) is made to work such that the value of <expr> will determine the exit status, according to the same interpretation that (exit <expr>) would give to the value. * sysif.[ch] (exit_wrap): Static function becomes external. * txr.c (txr_main): In the cases where we execute a file and return from main, we now call exit_wrap instead. The termination status is not simply based on whether the file was successfully read, but takes into account the load block. * tests/019/load-ret/{script.tl,bad.tl}: New files. * tests/019/load-ret/load-ret.tl: New tests. * txr.1: Documented.
* print: print/read consistency problem with rcons.Kaz Kylheku2023-12-082-1/+11
| | | | | | | | | | * lib.c (obj_print_impl): Do not print (rcons X Y) as X..Y if X looks like (rcons ...). This causes the problem that (rcons (rcons 1 2) 3) prints as 1..2..3, a notation which unambiguously means (rcons 1 (rcons 2 3)). * tests/012/syntax.tl: New test cases.
* quips: adjust Kant joke.Kaz Kylheku2023-12-061-1/+1
| | | | * stdlib/quips.tl (%quips%): Wording change.
* doc: fix "an" typos.Kaz Kylheku2023-12-031-13/+13
| | | | | * txr.1: Fix numerous "an" articles that should be "a", as well as one case of "and" missing a "d".
* doc: quasiquote: note about special quote splice.Kaz Kylheku2023-12-031-0/+44
| | | | | | | | * txr.1: Add dialect note about TXR supporting ,',*args whereby multiple items get spliced into a quote, which effectively distributes into multiple quotes. The direct equivalent does not work in all Common Lisp implementations, and doesn't appear to be required by the standard.
* doc: typo under rlink.Kaz Kylheku2023-11-251-1/+1
| | | | * txr.1: fix transposition: "ot" -> "to".
* sh-esc: clean up mess I made.Kaz Kylheku2023-11-253-31/+113
| | | | | | | | | | | | | | | | | | | | | | Not all special characters can just be backslash escaped. Spaces and newlines must be quoted. * stream.c (sh_esc_common): New function. Handles both sh-esc and sh-esc-all logic, distinguished by a flag. Quoting is used, rather than backslash escaping. If the string contains no special characters, it is just erturned. If it can be double quoted, it is double quoted. Otherwise it is single quoted and any contained single quotes are replaced by '\''. (sh_esc, sh_esc_all): Now just wrap sh_esc_common. (sh_esc_dq): Remove the newline from the set of escaped characters. Escaping a newline generates a continuation sequence which eats the newline. * tests/018/sh-esc.tl: Most test cases deleted; many new test cases added. * txr.1: Documentation revised.
* glob: suppress consecutive duplicates; fix memleak.Kaz Kylheku2023-11-222-12/+23
| | | | | | | | | | | | | | | | | | | * glob.c (glob_wrap): When converting the glob array to the returned list, suppress consecutive duplicates. This has to be done separately for each call to glob or super_glob, so we now interleave the production of the output list with the glob calls. It has to be done separately because there can be duplicates between different patterns. E.g. if (glob "?") matches one path then (glob '("?" "?")) must return two copies of it. Furthermore, the brace expansion implementation in glob* produces multiple glob calls and appends their results. Duplicates inside a single super_glob call result when there are multiple ** (double star) patterns present, which are matched by the same path in more than one way. If the results are sorted, then the duplicates appear consecutively and we will squash them. Also, a memory leak is fixed here: we must free(pat_u8) unconditionally, before testing for the early exit situation.
* tests: fix FFI libpng setjmp test case for Solaris 10.Kaz Kylheku2023-11-201-1/+2
| | | | | | | * tests/017/setjmp.tl: Solaris has libpng.so, but but some version without png_set_longjmp_fn. We add a test for the presence of this function as a precondition for running the real test.
* Version 292.txr-292Kaz Kylheku2023-11-207-1233/+1412
| | | | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated. * protsym.c: Regenerated.
* time: bug: must subtract gmtoff, not add.Kaz Kylheku2023-11-192-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This works fine: 1> (time-struct-utc 0) #S(time year 1970 month 1 day 1 hour 0 min 0 sec 0 wday 4 yday 0 dst nil gmtoff 0 zone "GMT") 2> *1.(time-utc) 0 3> *1.(time-local) 28800 But we want the following to return the same results: 1> (time-struct-local 0) #S(time year 1969 month 12 day 31 hour 16 min 0 sec 0 wday 3 yday 364 dst nil gmtoff -28800 zone "PST") 2> *1.(time-utc) -57600 3> *1.(time-local) -28800 With the patch, we do: 1> (time-struct-local 0) #S(time year 1969 month 12 day 31 hour 16 min 0 sec 0 wday 3 yday 364 dst nil gmtoff -28800 zone "PST") 2> *1.(time-utc) 0 3> *1.(time-local) 28800 This is also broken: 1> (time-parse-utc "%H:%M:%z" "00:00:-0800") -28800 It must return 28800. * time.c (time_meth): This function, which is the imlpementation of the time-utc and time-local methods, must subtract the gmtoff field, not add it. This is so that a UTC time expressed in a local time zone will convert back to the correct UTC epoch. (time_parse_local, time_parse_utc): Here we likewise must subtract the gmtoff.
* stdlib/error.tl problem rears its head.Kaz Kylheku2023-11-163-36/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There used to be a hack in the Makefile whereby the compilation of stdlib/error.tl was forced to occur earlier. I got rid of it. Now, the issue that was solving reproduced. A situation can occur whereby loading error.tl triggers loading some other files, which end up performing an expansion that needs sys:bind-mac-check: but that function has not yet been defined because error.tl has not yet loaded that far. The issue occurs when stdlib/place.tl is compiled before stdlib/error.tl. The compiled place.tl has a run-time dependency on functions in error.tl, because the compiled version of mac-param-bind and other forms relies on a run-time support function sys:bind-mac-check defined in stdlib/error.tl. * stdlib/error.tl (sys:dig): This function triggers the problem, but it's not the only cause. Here, the problem is because the (set ...) macro is used which triggers loading the stdlib/place module. That brings in the need for bind-mac-params. So here we use sys:setq instead. That is not a complete solution. The changes in eval.c are also required, because built-in macros like whilet expand to code that uses the (set ...) macro. Note how sys:dig uses whilet. (sys:bind-mac-check, sys:bind-mac-error): We move these functions above compile-warning. This addresses remaining circularity problem. The compile-warning function uses the catch macro which brings in stdlib/except.tl, which pulls in stdlib/op.tl due to its use of (do ...), which pulls in stdlib/place.tl. So if we already define sys:bind-mac-check at that point, we are good. * eval.c: Sweep the file for almost all places where macros generate code that invokes (set <symbol> <value>) and replace that with (sys:setq <symbol> <value>) to eliminate the dependency on loading the stdlib/place.tl module. (me_def_variable, me_gun, me_while_until_star, me_case, me_whilet, me_mlet, me_load_for, me_pop_after_load): In all these macro expanders, use sys:setq rather than set in the generated code. * tests/019/load-hook.tl: Some test cases here look for a macro expansion containing (set ...), needing to be fixed to look for (sys:setq ...) due to the change in eval.c.
* doc: incorrect description of rlink.Kaz Kylheku2023-11-151-3/+7
| | | | | * txr.1: The rlink function resolves the target path if it is a symlink, not the new link's path.
* doc: fix wrong typesetting of nil and t.Kaz Kylheku2023-11-151-13/+13
| | | | | | | | * txr.1: Fix numerous occurrences of nil and t being typeset using "meta" rather than "code". That makes them slanted in the HTML and PDF, and appear in angle brackets as <nil> and <t> in text-based man output. We want a non-slanted type, and no angle brackets for these.
* oop: allow del on struct sequences.Kaz Kylheku2023-11-153-4/+63
| | | | | | | | | | * lib.c (dwim_del): Remove check against structures from OBJ case; we just let this pass through to the logic that invokes replace. * tests/012/aseq.tl: New test cases. * txr.1: Document how del works on a [obj index] place.
* oop: segfault in special methods cache.Kaz Kylheku2023-11-152-11/+34
| | | | | | | | | | | | | * struct.c (invalidate_special_slots): New static function. (invalidate_special_slot_nonexistence): Move static function up in file, to be next to invalidate_special_slots. (make_struct_type, static_slot_ens_rec): Call the new invalidate_special_slots function in addition to calling static_slot_home_fixup whenever the stslots array is resized. The spslot array contains pointers to the elements of stslots, which become invalid when that is resized. * tests/012/oop-seq.tl: Repro test case added.
* dwim: correction to error diagnostic.Kaz Kylheku2023-11-151-1/+1
| | | | | | | * lib.c (dwim_set): The "not a place" diagnostic applies not only in situations when the object is a list; the diagnostic should not imply that the argument is a list when it isn't.
* New accessor: mref.Kaz Kylheku2023-11-156-0/+308
| | | | | | | | | | | | | | * eval.c (eval_init): Register mref intrinsic. * lib.[ch] (mref): New function. * stdlib/place.tl (sys:mref1): New place. (mref): New place macro, defined in terms of sys:merf1, ref place and mref function. * tests/012/seq.tl: New tests. * txr.1: Documented.
* place: bad indentation.Kaz Kylheku2023-11-131-9/+9
| | | | * stdlib/place.tl (dwim): Fix incorrect indentation.
* ref: bugfix in deletion of ref place.Kaz Kylheku2023-11-113-85/+100
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ref function is not defined in the documentation as an accessor, but there is a ref place. Unfortunately, deletion is broken: (del (ref x y)) does not store the new sequence back into place x, and so it does not work correctly for lists; if x is a list, it doesn't change. Various accessors are defined in terms of ref, as place macros, such as the first, second, third, ... accessors. This fixes the bug for them also; (del (second list)) must update list. * stdlib/place.tl (ref): Fix the delete-expander to fetch the clobber expander of the sequence place, and use the simple setter to put the edited sequence into that place. * tests/012/seq.tl: Test case, which breaks without this fix. Test the (second ...) place also, which is defined in terms of ref. * txr.1: Split documentation for ref and refset, mainly because one is an Accessor and one is a Function. Removing some discussions about the equivalences between DWIM brackets and ref; there are subtleties there not worth going into. Description of refset is simplified. We mention the possibility of del over a ref place; only in that case is the sequence itself required to be a place.
* New macro: tap.Kaz Kylheku2023-11-084-1/+82
| | | | | | | | | | | * autoload.c (op_set_entries): Add tap symbol as autoload trigger for op module. * stdlib/op.tl (tap): New macro. * tests/012/op.tl: New test. * txr.1: Documented.
* quips: philosphy-related joke.Kaz Kylheku2023-11-051-0/+1
| | | | * stdlib/quips.tl (%quips%): New one.
* match: translate some match-case forms into casequal.Kaz Kylheku2023-10-222-32/+102
| | | | | | | | | | | | | | | | | | | The motivation here is that casequal brings in some optimizations not done by match-case, like hashed lookup and jump tables. * stdlib/match.tl (non-triv-pat-t): Move temporary definition higher in file since it is needed earlier in the bootsrapping. (match-case-to-casequal): New function. (match-case): Try converting clauses to casequal with new function. If that returns something, use that as the expansion, otherwise perform the normal expansion. * txr.1: Documentation revised. Existing text is wrong which says that the clauses of a caseq, caseql or casequal are always evaluated sequentially. Furthermore, now that match-case and match-ecase can be transformed to casequal, they also don't necessarily evaluate sequentially. We spell out the conditions under which they may translate.
* build: revise build instructions in configure scriptKaz Kylheku2023-10-151-3/+4
| | | | | * configure: make it clear that the user must run "make" or "make all" before "make tests" and "make install".
* match: bug: missing autloads.Kaz Kylheku2023-10-151-1/+7
| | | | | | * autoload.c (match_set_entries): We must not just intern match-error, but load the function if it is referenced. Likewise, we must register an autoload for sys:match-pat-error.
* vim: bug: recognize char escapes in quasilit.Kaz Kylheku2023-10-141-1/+1
| | | | | | | * genvim.txr (txr_quasilit): Fix gaping omission here: the quasiliteral region does not contain any of the character escapes, screwing up the syntax highlighting if any of them occur.
* build: misspelled PLATFORM_LDLIBS.Kaz Kylheku2023-10-061-1/+1
| | | | | | * Makefile (TXR_LDLIBS): Fix PLAFORM_LDLIBS typo in definition of variable. This typo renders ineffective the --platform-ldlibs option of the configure script.
* New: length-list-<, length-<Kaz Kylheku2023-10-055-0/+138
| | | | | | | | | | | | | | | | | | | | | | These are functions for testing whether a list or sequence is shorter than a given integer. This is cheaper than calculating the length of lists, which is in some cases impossible if they are infinite. A length-str-< function already exists, useful with lazy strings. length-< uses length-list-< or length-str-< as appropriate * lib.[ch] (length_list_lt, length_lt): New functions. * eval.c (eval_init): length-list-< and length-< intrinsics registered. * tests/012/seq.tl: New tests. * txr.1: Documented.
* doc: small omission in flatcar.Kaz Kylheku2023-10-051-0/+4
| | | | | * txr.1: Document that flatcar and flatcar* accept an atom argument, which is returned.
* tests for flatcar and flatcar*.Kaz Kylheku2023-10-011-0/+24
| | | | * tests/012/seq.tl: New tests.
* flatten*: fix two bugs.Kaz Kylheku2023-09-303-14/+86
| | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (lazy_flatten_scan): Fix a problem which results in cases like (()), ((())) ... to incorrectly flatten to (nil). The do loop in this function which iteratively descends into a nested left-nesting of a list does not handle all cases, and therefore the function may not return at that point. Removing the return fixes the problem, but so does removing the loop so that in that case we just descend one level into the nested list, and continue in the main loop. What is incorrect is that when the consp(a) test fails and the do loop terminates, we need to distinguish the cases off a being an atom versus nil. Continuing in the loop does that. This bug was spotted by a reviewer in the comp.lang.c Usenet newsgroup. (lazy_flatten): We neglect to handle the case here that the input is an empty list, resulting in (flatten* nil) returning (nil) rather than nil. The flatten function is correct. * tests/012/seq.tl: New tests. * txr.1: Documentation improved. In particular, these functions don't handle improper lists. Also, it needs to be documented that the argument may be an atom.
* Integration with setjmp/longjmp.Kaz Kylheku2023-09-279-1/+315
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Defining libpng bindings, with longjmp catching, is now possible. * autoload.c (ffi_set_entries): Add setjmp symbol, which is a new macro in stdlib/ffi.tl. * ffi.c (jmp_buf_s): New symbol variable. (mk_jmp_buf, rt_setjmp, longjmp_wrap): New functions. (ffi_init): Initialize jmp_buf_s. Register sys:rt-setjmp and longjmp intrinsics. * ffi.h (jmp_buf_s): Declared. * stdlib/ffi.h (setjmp): New macro. Rather than introducing a new special operator, we use a run-time support function called sys:rt-setjmp, which takes functional arguments. * unwind.[ch] (uw_snapshot, uw_restore): New functions. The rt_setjmp function needs these to restore our unwind frame stack into a sane state after catching a longjmp, which bails without unwinding it, leaving the pointers referring to frames that no longer exist. * tests/017/setjmp.tl, * tests/017/setjmp.expected: New files. * txr.1: Documented.
* New hist-sort function.Kaz Kylheku2023-09-255-4/+75
| | | | | | | | | | | | | | | * eval.c (eval_init): Register hist-sort intrinsic. * lib.c (gt_f): New global variable. (hist_succ_f): New static variable. (hist_succ): New static function. (hist_sort): New function. * lib.h (gt_f, hist_sort): Declared. * tests/012/sort.tl: New tests. * txr.1: Documented.
* New T mode for open-file.Kaz Kylheku2023-09-233-4/+70
| | | | | | | | | | | | | | | The T mode uses O_TMPFILE to create an unlinkd temporary file. * stream.h (struct stdio_mode): New flag, tmpfile. (stdio_mode_init_blank, stdio_mode_init_r, stdio_mode_init_rpb): Updated to cover new bitfield member. * stream.c (w_open_mode): If tmpfile flag is on, add O_TMPFILE. (do_parse_mode): Recognize "T" mode selector and set all appropriate mode bits. If we are not on a platform that has O_TMPFILE, set the maformed flag. * txr.1: Documented.
* New function: rlink.Kaz Kylheku2023-09-233-4/+55
| | | | | | | | | | | | | | | This uses the linkat function to implement a variant of link which resolves the source object if it is a symlink. * configure: test for linkat. * sysif.c (link_wrap_common): New static function, used by both link_wrap and rlink_wrap. (link_wrap): Now a one-liner which calls link_wrap_common. (rlink_wrap): New static function. (sysif_init): Register rlink intrinsic. * txr.1: Documented.
* doc: awk: records and fieldsKaz Kylheku2023-09-221-1/+1
| | | | | * txr.1: the awk macro divides input into records and fields, not records or fields.
* doc: fix "uninterested symbols".Kaz Kylheku2023-09-221-1/+1
| | | | | * txr.1: in description of weak packages, fix "uninterested" symbols to "discarded".
* doc: fix wording problem in hash-map.Kaz Kylheku2023-09-221-5/+9
| | | | | * txr.1: Fix hash-map being described as constructing a function. It returns a hash table. Revise wording.
* build: set DELETE_ON_ERROR in Makefile.Kaz Kylheku2023-09-221-0/+2
| | | | | | | * Makefile (.DELETE_ON_ERROR): Special target added. The GNU Make manual says that this is what we always want. Without this, a partially generated txr-manpage.html target is not removed if the recipe happens to die.
* doc: fix instances arguments-apply-to-function wording.Kaz Kylheku2023-09-221-21/+27
| | | | | | | | * txr.1: Revise all wording which says that arguments are applied to a function, or other object being used as a function. I seem to remember taking the same initiative some years ago, but wrong usages have snuck in. I even found some in the definition of the apply function.
* New functions: nested-vec-of and nested-vec.Kaz Kylheku2023-09-217-20/+185
| | | | | | | | | | | | | | | * eval.c (eval_init): Register nestd-vec-of and nested-vec intrinsics. * lib.[ch] (vec_allocate, vec_own, vec_init): New static functions. (vector, copy_vec): Expressed in terms of new functions. (nested_vec_of_v, nested_vec_v): New functions. * args.[ch] (args_cat_from): New function. * tests/010/vec.tl: New tests. * txr.1: Documented.
* doc: glob*: spellingKaz Kylheku2023-09-131-2/+2
| | | | * txr.1: Typos in recently added paragraphs.
* glob*: Solaris fixes.Kaz Kylheku2023-09-132-26/+29
| | | | | | | | | | | | | * glob.c (glob_wrap): #ifdef GLOB_BRACE around code that removes the flag. (super_glob_find_inner): Initialize pst. The older compiler I'm using on Solaris 10. isn't smart enough to figure out that it is not used uninitialized. * tests/018/glob.t: Skip the ...\/** test on Solaris. It takes a long time, and produces nil in the end. We don't care how it behaves, only that we pass through that pattern to glob without interpreting it as a double star.
* glob*: skip tests on Cygwin.Kaz Kylheku2023-09-131-0/+4
| | | | * tests/018/glob.tl: exit successfully on Cygwin.
* glob*: fix buggy sort comparison function.Kaz Kylheku2023-09-132-91/+97
| | | | | | | | * glob.c (glob_path_cmp): Compare bytes as unsigned. After the loop, don't test whether the pointer are null; they never are. Test whether they point to null. * tests/018/glob.tl: Expected data replaced.
* glob*: do not recognize trailing \/**.Kaz Kylheku2023-09-132-1/+31
| | | | | | | * glob.c (super_glob_rec): Do not recognize a trailing /** if it is preceded by a backslash. * tests/018/glob.tl: Test case added.