summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* utf8: bugfix: trailing char fragment ignored.Kaz Kylheku2022-05-202-0/+16
| | | | | | | | | | | | | | | | | | | | After "years of trouble-free operation" a bug in the UTF-8 decoder was found, which violates its property that any sequence of bytes will decode to some kind of string, which will encode to the original bytes. When the UTF-8 data prematurely ends in the middle of a valid character, the decoder just drops that data as if it didn't exist. So for instance the two-byte sequence E6 BC should decode to "\xDCE6\xDCBC", since it is a fragment of a three-byte UTF-8 sequence. It actually decodes to the empty string. * utf8.c (utf8_bfom_buffer): When the buffer is exhausted, if we are not in the utf8_init state, it means we were in the middle of a UTF-8 sequence. Walk the bytes from the backtrack point to the end of the buffer and store them into the string as U+DCxx codes. * tests/012/buf.tl: Tests added for this via buf-str, str-buf.
* ffi: pack bugfix and tests.Kaz Kylheku2022-05-203-12/+149
| | | | | | | | | | | | | | * ffi.c (ffi_transform_pack): Fix: return the original syntax in the situation when no cases are recognized, rather than the cdr of the syntax. When the struct/union syntax has no members, return the original syntax to indicate no transformation took place. * txr.1: Document the feature that pack on a typedef name or struct name with no members will do the alignment adjustment only, without the syntactic transformation. * tests/017/pack-align.tl: New file.
* eval: remove message about --backtrace option.Kaz Kylheku2022-05-201-4/+0
| | | | | | | * eval.c (error_trace): Don't mention that --backtrace can be used to enable backtraces. This is not only a nuisance, but appears in packaged programs which do not support such an option, making it highly misleading.
* doc: quasiliteral match: formatting problem.Kaz Kylheku2022-05-201-1/+1
| | | | | * txr.1: fix broken quoting which results in stray " character appearing in rendered output.
* doc: undimensioned arrays may be flexible array members.Kaz Kylheku2022-05-201-4/+9
| | | | | | | * txr.1: The documentation for array and zarray wrongly states that if the dimension is omitted, the type may not be used as a structure member. In fact, it may be used as the last member of a flexible structure.
* doc: grammarKaz Kylheku2022-05-201-2/+2
| | | | * txr.1: two instances of "an incomplete arrays" in FFI doc.
* ffi: behavior of align subject to compat.Kaz Kylheku2022-05-202-1/+18
| | | | | | | * ffi.c (ffi_type_compile): Allow align to weaken (lower) alignment if compatibility 275 or lower is requested. * txr.1: Compat note added.
* ffi: pack: implement documented align transformation.Kaz Kylheku2022-05-201-19/+32
| | | | | | | | | | | * ffi.c (ffi_pack_members): Static function removed. (ffi_transform_pack): New static function. (ffi_type_compile): Rely on ffi_transform_pack to recognize and perform all necessary transformations. Cosmetic issue: when a struct is compiled, and the individual member types undergo transformation during member compilation, the syntax for the struct is nevertheless the original one with the untransformed members.
* New function: trim-path-sepsKaz Kylheku2022-05-205-0/+111
| | | | | | | | | | | | | * stream.c (trim_path_seps): New function. (stream_init): trim-path-seps intrinsic registered. * stream.c (trim_path_seps): Declared. * tests/018/path.tl: New tests. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* ffi: bugfix: clone of type points to old self.Kaz Kylheku2022-05-201-2/+6
| | | | | | | | | | | | * ffi.c (ffi_type_copy, ffi_type_copy_new_ops): The cloned txr_ffi_type structure must have a self member which points to the new cobj, not the original one. Otherwise things are inconsistent. For instance if the clone is being made for the purposes of adjusting alignment, any operation which chases the self pointer will be accessing incorrect attributes. One example of this is (alignof foo.bar) where if bar is the clone of a type, this will incorrectly report the alignment of the original from which bar was cloned, and the original alignment, not the adjusted alignment is reported.
* ffi: new pack type operator; align increases only.Kaz Kylheku2022-05-203-38/+237
| | | | | | | | | | | | | | | | | * ffi.c (pack_s): New symbol variable. (ffi_type_compile): Handle new pack type operator together with align. Allow a one-argument form of align and pack in which the value is defaulted. The behavior of align changes: align can only increase alignment now, never decrease, so for instance (align 1 ...) does nothing. pack must be used to decrease alignment. Furthermore, for certain argument types, pack performs transformations of the type syntax, rather than compiling the argument type and producing a variant of it with altered alignment. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* ffi: bugfix: transition between bitfield cell sizes.Kaz Kylheku2022-05-191-0/+10
| | | | | | | | | * ffi.c (make_ffi_type_struct): When a bitfield is declared for a type whose alignment is different from that of the previous member, then we start the new bitfield on a fresh alignment. As usual, if the previous member is a bitfield which left a partially filled byte, we skip to the next byte and then do the alignment. This seems to match GCC behavior.
* ffi: bitfield handling when storage cells are packed.Kaz Kylheku2022-05-191-11/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In gcc, bitfields can be declared with overridden alignment; for instance when the entire structure is packed. We must modify the algorithm to make this work. Firstly, we must must pretend that we are filling from the start of the containing alignment unit, not size based unit. For instance, if the cell is an 8 byte type, but the alignment is 1, then we are just filling the current byte, not the current 8 byte multiple. However, the number of bits left (room) is still calculated from the size: so if the byte has been filled with 3 bits, we have 4 left in that byte, and then 7 more bytes, and so 61 bits. Secondly, the case of the zero-bit field is special: it does perform an alignment calculation in terms of multiples of the size, ignoring the declared alignment of the field. Thirdly, when the bits do not fit into the existing room, the offset does not move by the size of the bitfield, but by the alignment unit. For instance, if we have 63 bits left in an 8 byte field that has alignment 1, and we want to place 64 bits into another 8 byte field, then we will just move to the next byte, not to the next 64 bit cell. Starting at the next byte, we pretend we have a fres 64 bit cell, albeit misaligned. * ffi.c (make_ffi_type_struct): Make the above adjustments to the algorithm. Some common values size, alignment, mask) are declared in a wider scope and adjustments made.
* ffi: bugfix: empty structs/unions have alignment of 1.Kaz Kylheku2022-05-192-2/+6
| | | | | | | | * ffi.c (make_ffi_type_struct, make_ffi_type_union): Initialize most_align local variable to 1, so the lower bound of alignment is that, rather than zero. * tests/017/ffi-misc.tl: Tests added.
* ffi: bugfix in fat bitfields.Kaz Kylheku2022-05-191-2/+2
| | | | | | | * ffi.c (make_ffi_type_struct, make_ffi_type_union): Do not fall back from the fat (64 bit) bitfield case to the regular (32 bit) case when the number of bits is less than 32. This is completely wrong.
* ffi: diagnose bitfields wider than type.Kaz Kylheku2022-05-191-6/+6
| | | | | | | | | * ffi.c (ffi_type_compile): Show the original bitfield syntax in the invalid size diagnostics. In the case of the (bit n type) syntax, restrict the maximum bits to the width of the type, not just to 32 or 64. I realize the 8 * tft->size calculation can overflow for huge array types, but it makes no sense to use them as bitfields.
* ffi: support 64 bit bitfields.Kaz Kylheku2022-05-192-22/+222
| | | | | | | | | | | | | | | | | | | | | | | | | * ffi.c (struct txr_ffi_type): Replace unsigned mask member with a union m which holds unsigned mask and 64-bit fmask (fat mask). (ffi_sbit_put, ffi_sbit_get, ffi_ubit_put, ffi_ubit_get): Refer to m.mask. (ffi_fat_sbit_put, ffi_fat_sbit_get, ffi_fat_ubit_put, ffi_fat_ubit_get): New static functions. (ffi_generic_fat_sbit_put, ffi_generic_fat_sbit_get, ffi_generic_fat_ubit_put, ffi_generic_fat_ubit_get): Likewise. (make_ffi_type_struct, make_ffi_type_union): Set up fat mask for bitfields that are wider than int. (ffi_type_compile): Refer to m.mask for the int and unsigned int based bitfields declared with sbit and ubit that don't mention a type. The bit operator now allows int64 and uint64 to be valid types for a bitfield. In this case, the "fat" get and put functions are selected which use 64 bit operations. Thus there is no efficiency impact on non-fat bitfields which continue to use code with 32 bit operands. (ffi_offsetof): Use the bitfield flag in the member's type structure to detect bitfields, rather than the mask.
* ffi: use longlong_t.Kaz Kylheku2022-05-191-4/+8
| | | | | | ffi.c (ffi_init_extra_types): Use longlong_t and ulonglong_t, subject to HAVE_LONGLONG_T. If there is no intmax_t and no longlong_t, don't define intmax-t and uintmax-t.
* ffi: eliminate trivial allocas in bitfield code.Kaz Kylheku2022-05-181-14/+14
| | | | | | * ffi.c (ffi_generic_sbit_put, ffi_generic_sbit_get, ffi_generic_ubit_put, ffi_generic_ubit_get): Replace int-sized alloca with declared int object.
* ffi: alignment bug in undimensioned arrays.Kaz Kylheku2022-05-182-8/+10
| | | | | | | | | | | | | | | | | | | | | | Because the varray behavior for undimensioned arrays was introduced in dubious commit 7880c9b565ab438e1bf0250a967acdbf8d04cb42 in 2017, which used make_ffi_type_pointer to register the type, claiming that the C representation is pointer (which was not true in that commit, nor ever since). As a result, though, undimensioned arrays received the alignment of pointers, rather than deriving it from the element type. Thus (array char) has 4 or 8 byte alignment whereas (array 4 char) correctly has 1 byte alignment. * ffi.c (ffi_type_compile): Use make_ffi_type_array for the two-element array syntax, just like for the dimensioned case with three elements. Then override some of the functions with the varray versions. * tests/017/ffi-misc.tl: Fix the test case which exposed this. In the type (struct flex (a char) (b (zarray char)), the array b must be at offset 1. I didn't notice that the offset of 4 being confirmed by the test case was wrong, but this showed up when running the test case on a platform with 8 byte pointers.
* ffi: fix broken test.Kaz Kylheku2022-05-181-2/+2
| | | | | | | * tests/017/ffi-misc.tl: Fix incorrect test whose loop body does not execute. A remaining issue here is why the diagnostics about unbound functions and variables in the loop body get swept under the rug.
* copy-path-rec: bug: trailing slash fail.Kaz Kylheku2022-05-171-4/+1
| | | | | | | | | * stdlib/copy-file.tl (copy-path-rec): When from-path has a trailing slash, the starts-with test fails, and the operation fails without doing anything. Let's just get rid of that test. It's probably only there because of the ad-hoc path munging that is calculating rel-path. Why don't we just use the rel-path function for that.
* split-str: new count parameter.Kaz Kylheku2022-05-175-13/+103
| | | | | | | | | | | | | | | | | | * eval.c (eval_init): Fix up registration of split-str to account for new parameter. * lib.c (split_str_keep): Implement new optional count argument. (spl): Pass nil value to split_str_keep for new argument. I'd like this function to benefit from this argument also, but the design isn't settled. (split_str): Pass nil argument to split_str_keep. * lib.h (split_str_keep): Declaration updated. * tests/015/split.tl: New tests. * txr.1: Documented.
* doc: grammar under pattern matching.Kaz Kylheku2022-05-171-1/+1
| | | | * txr.1: agreement between "body" and "consist".
* ffi: bugfix: null terminated string as flexible member.Kaz Kylheku2022-05-172-38/+34
| | | | | | | | | | | | * ffi.c (ffi_char_array_get, ffi_zchar_array_get, ffi_wchar_array_get, ffi_bchar_array_get): Rearrange so that we test for tft->null_term first, and not nelem == 0. If nelem happens to be zero, but we are supposed to decode a null-terminated string, we will do the wrong thing and return the null string. (ffi_varray_in): The body can't be conditional on vec being non-nil, because then we do nothing if we don't have a Lisp object, which means we skip the cases when we should decode a null-terminated array. Now if vec is nil, we must guard against calling ffi_varray_dynsize.
* ffi: bugfix: unions are not unconditionally incomplete.Kaz Kylheku2022-05-171-1/+1
|
* New options: --in-package and --compile.Kaz Kylheku2022-05-123-3/+98
| | | | | | | | | * txr.c (help): Mention new options. (do_compile_opt, do_in_package_opt): New static functions. (txr_main): Implement options. * Makefile (COMPILE_TL): Use the options instead of -e. * txr.1: Document.
* expander: new rule for macro-produced function callsKaz Kylheku2022-05-122-1/+136
| | | | | | | | | | | | | | * eval.c (do_expand): When a function call's arguments are expanded and produce a transformation, then if that function call had been produced by a macro, the transformed function call is tried again as a macro. This is necessary because TXR Lisp allows a symbol to be both a function and macro. When a macro-produced function call's arguments are expanded, the macro version of that function may, as a result of the argument transformations, have more opportunities for expansion. * txr.1: New section outlining how macro expansion generally works, with a special focus on this unusual new rule.
* Print ([...] . @var) and ([...] . @(expr)) notation.Kaz Kylheku2022-05-111-2/+11
| | | | | | | | | | | This change fixes objects like (@a @b . @c) being printed as (@a @b sys:var c). This is piggybacked into the logic which renders dotted unquotes. In other words, we are already printing (x . ,y) in that from rather than (x sys:unquote y); we just recognize sys:var, and sys:expr in the same code. * lib.c (obj_print_impl): Recognize dotted metavariables and metaexpressions similarly to dotted unquotes.
* lambda-match: bug: over-strict match in variadic pattern.Kaz Kylheku2022-05-112-1/+15
| | | | | | | | | | | | * stdlib/match.tl (expand-lambda-match): A pattern that is shorter than the maximum number of arguments is augmented with a check ensuring that no fixed arguments are present beyond those that the pattern requires. However, this check must be omitted if the pattern is variadic, because those excess arguments match its tail pattern. * tests/011/patmatch.tl: Cases added.
* Version 275.txr-275Kaz Kylheku2022-05-107-1585/+1632
| | | | | | | | | | | | | | * 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: Likewise.
* tests: Cygwin fixes.Kaz Kylheku2022-05-103-14/+18
| | | | | | | | | | | * tests/017/str-s.tl: Use (libc) not nil in with-dyn-lib. * tests/018/forkflush.tl: On Cygwin, produce canned output for first test case, because the real test case produces some DOS line endings that cause a mismatch. * tests/019/load-search.tl: Skip test case involving a directory with bad permissions being in the load search path.
* Support Loongarch.Kaz Kylheku2022-05-102-0/+81
| | | | | | * jmp.S (jmp_save, jmp_restore): Define for Loongarch. * unwind.h (struct jmp): Likewise.
* ffi: fix broken on RISC-V.Kaz Kylheku2022-05-101-1/+1
| | | | | | | | | | | | | | * ffi.c (pad_retval): Remove the special case of zero mapping to zero, which occurs when the return type is void. It's not clear whether this is correct at all, on any platform. It hasn't showed up as a problem until now, but on RISC-V, we have hit a situation in which ffi_call writes a value into that zero-byte space for the void return value, causing that to overwrite values[0]: the first element of the argument array. For reasons not understood, this happens in the qsort test cases in which which the callback function performs a block return. It is strange because the block return is handled entirely in the closure dispatching function.
* Support RISC-V: conditionally.Kaz Kylheku2022-05-102-0/+105
| | | | | | | | | | | | | | | | | | | | | | Everything compiles, and most tests pass. Failing test are: - tests/014/dgram-stream.tl: - tests/017/glob-carray.tl: - tests/017/qsort.tl: The datagram test is not able to bind a UDP socket to a port. On the gcc402 machine of the GCC Compile Farm, attempts bind a UDP socket to any of the ports 1024-65535 all fail with errno 99 (EADDRNOTAVAIL). The FFI test cases are segfaulting. The qosrt.tl case has the problem in the test cases which abort the callback with a return-from. * unwind.h (struct jmp): Define for RISC-V. * jmp.S (DEFUN): Define macro for RISC-V. (jmp_save, jmp_restore): Define for RISC-V.
* linenoise: Ctrl-Z: send SIGTSTP to group, not self.Kaz Kylheku2022-04-281-3/+3
| | | | | | | | | | | | | | | | | | | I realized this issue while implementing Ctrl-Z for the pw (Pipe Watch) program. Sending the SIGTSTP signal just to the calling process is not enough. Only that process gets suspended, which results in a weird behavior. It can be tested like this, for instance: txr | tee file Ctrl-Z must be issued twice: once to sort of suspend txr, and then again to send it to the tee program. Then the job actually suspends and the shell prompt appears. With this fix, the above situation requires only one Ctrl-Z, as expected. * linenoise/linenoise.c (history_search, show_help, edit): Don't raise(SIGTSTP), but kill(0, SIGTSTP) to send the suspend signal to all processes in the process group.
* doc: FFI string types map null pointer to nil.Kaz Kylheku2022-04-261-3/+7
| | | | | | * txr.1: Document the existing behavior that the various FFI string types map between the null pointer and the nil object.
* doc: ffi: document the array-of-1 trick.Kaz Kylheku2022-04-261-0/+62
| | | | | * txr.1: Document the (ptr (array 1 <type>)) trick needed for out or in-out parameters.
* load/@(load): use path_cat.Kaz Kylheku2022-04-252-6/+2
| | | | | | | * eval.c (load): Use path_cat and dir_name instead of ad hoc path munging. * match.c (v_load): Likewise.
* *load-search-dir*: Some tests.Kaz Kylheku2022-04-251-0/+33
| | | | | * tests/019/load-search.tl: Add some cases that explore the load search path.
* New: load can search multiple directories.Kaz Kylheku2022-04-258-19/+131
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (load_search_dirs_s): New symbol variable. (load): Initialize the name variable whose address is passed as the third argument of open_txr_file, which is now an in-out parameter. Pass t for the new search_dirs parameter, so that load benefits from the searching. (eval_init): Initialize load_search_dirs_s and register the *load-search-dirs* special variable. * eval.h (load_search_dirs_s): Declared. (load_search_dirs): New macro. * match.c (v_load): Initialize the variable passed as third argument of open_txr_file. * parser.c (open_txr_file): Take a new argument, search_dirs. If this is t, it tells the function "if the path is not found, then recurse on the *load-search-dirs* variable. Otherwise, if the value is not t, it is a list of the remaining directories to try. The existing parameter orig_in_resolved_out must now point to a location which is initialized. It is assumed to hold the original target that was passed to the load function. The first_try_path is a the path to actually try, derived from that one. Thus, the caller of open_txr_file gets to determine the initial try path using its own algorithm. Then any recursive calls that go through *load-search-dirs* will pass a first argument which is made of the original name, combined with a search dir. (load_rcfile): Pass pointer to initialized location as third argument of open-txr_file, and pass a nil value for search_dirs: no search takes place when looking for that file, which is at a single, fixed location. * parser.h (open_txr_file): Declaration updated. * txr.c (sysroot_init): Initialize *load-search-dirs*. (txr_main): Ensure third argument in all calls to open_txr_file points to initialized variable, with the correct value, and pass t for the search_dirs argument. * txr.1: Documented. * stdlib/doc-syms.tl: Updated. New: load can search multiple directories. * eval.c (load_search_dirs_s): New symbol variable. (load): Initialize the name variable whose address is passed as the third argument of open_txr_file, which is now an in-out parameter. Pass t for the new search_dirs parameter, so that load benefits from the searching. (eval_init): Initialize load_search_dirs_s and register the *load-search-dirs* special variable. * eval.h (load_search_dirs_s): Declared. (load_search_dirs): New macro. * match.c (v_load): Initialize the variable passed as third * argument of open_txr_file. * parser.c (open_txr_file): Take a new argument, search_dirs. If this is t, it tells the function "if the path is not found, then recurse on the *load-search-dirs* variable. Otherwise, if the value is not t, it is a list of the remaining directories to try. The existing parameter orig_in_resolved_out must now point to a location which is initialized. It is assumed to hold the original target that was passed to the load function. The first_try_path is a the path to actually try, derived from that one. Thus, the caller of open_txr_file gets to determine the initial try path using its own algorithm. Then any recursive calls that go through *load-search-dirs* will pass a first argument which is made of the original name, combined with a search dir. (load_rcfile): Pass pointer to initialized location as third argument of open-txr_file, and pass a nil value for search_dirs: no search takes place when looking for that file, which is at a single, fixed location. * parser.h (open_txr_file): Declaration updated. * txr.c (sysroot_init): Initialize *load-search-dirs*. (txr_main): Ensure third argument in all calls to open_txr_file points to initialized variable, with the correct value, and pass t for the search_dirs argument. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* open_txr_file: rename parameters.Kaz Kylheku2022-04-242-20/+20
| | | | | | * parser.[ch] (open_txr_file): spec_file is now called first_try_path. The name parameter is called orig_in_resolved_out. Currently it has just the resolved_out semantics, but that is about to change.
* subprocesses: don't unnecessarily flush *stdout*.Kaz Kylheku2022-04-241-2/+4
| | | | | | * stream.c (open_subprocess, open_commad): Only flush standard output for non-input pipes. If we are capturing the output of the process, then it is unrelated to our standard output.
* subprocesses: flush *stdout*.Kaz Kylheku2022-04-231-0/+8
| | | | | | * stream.c (open-subprocess, open_command, run): Flush the standard output stream before forking or spawning the child process. This gets tests/018/forkflush.tl to pass.
* fork/streams: new failing test.Kaz Kylheku2022-04-232-0/+43
| | | | | | | | | | | | | | | | This test case exemplifies code that will work as expected when *stdout* is a TTY device, such that line buffering is in effect, but then break when standard output is redirected to a file. The issue is that the controlling process is not flushing its standard output when calling the external script, so the script's output gets placed ahead of the process' own earlier output. * tests/018/forkflush.tl: New file. * tests/018/forkflush.expected: New file.
* doc: cross reference eval and file compilation.Kaz Kylheku2022-04-011-2/+33
| | | | | | | * txr.1: The Top-Level Forms and File Compilation Model sections now reference back to eval, noting its similar treatment of top-level forms. Without this, it looks like top-level forms are just a compilation concept.
* loading: bugfix: try specified path before suffixes.Kaz Kylheku2022-03-312-61/+99
| | | | | | | | | | | | | | | | | | | | This is a partial revert of the May 1, 2019 commit 065dde19dfbe50e91e313e5b3ccc033cfbe47f74, titled "loading: try unsuffixed files directly last". Test cases added in prior commit now pass. * parser.c (open_txr_file); Like before the 2019 commit, we try the exact path that is specified first. Only if that is not found do we try adding suffixes to a file which has no recognizable suffix. This does mean that (load "foo") will probe the filesystem twice in order to find "foo.tl" or "foo.tlo" there is no obvious way around that that doesn't cause a problem. * txr.1: Update documentation that is outdated, incomplete, incorrect, or that is has become incorrect because of this fix.
* Add test for loading issue.Kaz Kylheku2022-03-3110-0/+55
| | | | | | | | | | | | | | | | | This test currently fails because when we execute an unsuffixed file like test/019/a, which exists, another file is executed instead, like test/019/a.txr. * tests/019/data/a, * tests/019/data/a.tl, * tests/019/data/a.tlo, * tests/019/data/a.txr * tests/019/data/b.tl * tests/019/data/b.tlo * tests/019/data/b.txr * tests/019/data/c.tl * tests/019/data/c.txr * tests/019/load-search.tl: New files.
* compiler: package-manipulating top-level forms bug.Kaz Kylheku2022-03-311-1/+2
| | | | | | | | | | | | | | * stdlib/compiler.tl (compile-file-conditionally): Recognize a potential package-manipulating form not checking whether its main operator is in %pakage-manip% list, but whether any global functions that its compiled image references are in that list. This is the same approach that is used in dump-compiled-objects. This fix is needed for correctly recognizing defpackage as a package-manipulating form. defpackage macro-expands to a let form which contains a call to make-package. Testing whether let is in %package-manip% is useless; of course it isn't, and the test overlooks make-package.
* New function: isecp.Kaz Kylheku2022-03-306-7/+52
| | | | | | | | | | | | | | | | | * eval.c (eval_init): Register isecp intrinsic. * lib.c (isecp): New function. * lib.h (isecp): Declared. * stdlib/compiler.tl (lambda-apply-transform, dump-compiled-objects): Use isecp instead of isec, since the actual intersection of symbols isn't needed, only whether it exists. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.