summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* doc-syms: update.Kaz Kylheku2021-08-151-3/+5
|
* getaddrinfo: implement canonname.Kaz Kylheku2021-08-153-5/+39
| | | | | | | | | | | | | | | | Paul A. Patience noted that the canonname_s variable is not used in the C code. This indicates that the AI_CANONNAME functionality of getaddrinfo isn't implemented. Let's do that. * stdlib/socket.tl (sockaddr): New slot, canonname. (addrinfo): Default canonname to nil, not 0, since it is a string that may be absent. * socket.c (getaddrinfo_wrap): If the first address object has a non-null ai_canonname and it was requested via the flags, then stick that name into every returned structure. * txr.1: Documented.
* doc: improve.Paul A. Patience2021-08-144-141/+149
| | | | | | | | | | | | * RELNOTES: Fix various minor issues and stylistic issues. * configure: Remove repeated word and add missing word. * txr.1: Fix various minor, not-so-minor and stylistic issues. In particular, struct-from-args was misspelled in the .mets line and open-subprocess was missing from the .coNP line. * stdlib/doc-syms.tl: Updated.
* ffi: remove redundant assignment.Paul A. Patience2021-08-141-1/+0
| | | | * ffi.c (int8_s): Remove redundant assignment.
* matcher: new must-match and must-match-case macros.Kaz Kylheku2021-08-134-5/+55
| | | | | | | | | | | | | * lisplib.c (match_set_entries): Intern the match-error symbol. Register autoloads for must-match and must-match-case. * stdlib/match.tl (match-error): Register exception symbol, as subtype of match-error. (must-match, must-match-case): New macros. * tests/011/patmatch.tl: Test cases. * txr.1: Documented.
* tests: support BSD flavors loosely, not just OpenBSD.Kaz Kylheku2021-08-135-5/+5
| | | | | | | | | | | | * tests/common.tl (os-symbol): Look for the substring BSD in the system name, and map to symbol :bsd. Do not produce the :openbsd symbol. * tests/014/socket-basic.tl: Refer to :bsd, not :openbsd. * tests/017/glob-carray.tl: Likewise. * tests/018/chmod.tl: Likewise.
* termios: FreeBSD has no TAB1 and TAB2.Kaz Kylheku2021-08-131-0/+8
| | | | | | * termios.c (termios_init): Separate the #ifdef conditions for the TAB* identifiers, instead of assuming that TABDLY covers them all.
* int-str: 0x bug.Kaz Kylheku2021-08-132-7/+58
| | | | | | | | | | | | | | | * lib.c (int_str): The problem here is that we are recognizing and skipping the 0x prefix for all bases. So for instance (int-str "0x123") produces 123. The correct requirement, and the intent of the code, is that the C conventions are only honored if the base is specified as the character #\c. In any other base, including omitted base defaulting to 10, a leading zero is just a leading zero, and 0x is a zero followed by the junk character x. Therefore, if we have any valid base that isn't #\c, and 0x has been seen, we must return zero. We must not do this only in the base 16 case. * tests/016/conv.tl: New file.
* configure: superfluous printf argument.Kaz Kylheku2021-08-131-4/+4
| | | | | | | * configure: In the test for an alignming malloc, fix a copy-and-paste error. The $try_header expansion is passed to printf, but there is nothing in the format string. FreeBSD printf diagnoses this and dies.
* parser: @(mdo) must not be subject to expand-meta.Kaz Kylheku2021-08-113-406/+411
| | | | | | | | | | | | | | | | | | | | * parser.y (elem): When the elem is a list, if it starts with mdo, then we evaluate it immediately and substitute (do) as the semantic value. We no longer not allow mdo to precipitate into match_expand_elem, where expand_meta will be unleashed on it. Doing so causes the bug that expessions like @1, denoting the form (sys:var 1), are rewritten to (sys:expr 1), which op syntax. So two bugs are fixed: the incorrect treatment of meta-syntax, and the neglect to perform mdo in nested contexts. (check_parse_time_action): We need not handle mdo here any more; it will never make it into this function. Only actions done in the main clause list belong here, not parse time actions done at any nesting level. * tests/008/mdo.txr: New file. * y.tab.c.shipped: Updated.
* txr: add tests for :nothrow handling process death.Kaz Kylheku2021-08-074-0/+12
| | | | | | | | | | * tests/007/except-3.txr: New file. * tests/007/except-3.expected: Likewise. * tests/007/except-4.txr: Likewise. * tests/007/except-4.expected: Likewise.
* Version 268.txr-268Kaz Kylheku2021-08-077-1351/+1390
| | | | | | | | | | | | | | * 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.
* windows: skip test requiring full Unicode.Kaz Kylheku2021-08-071-0/+3
| | | | | * tests/012/cont.tl: Exit before the test case that contains characters ouside of the BMP, if (sizeof wchar) is less than 4.
* lazy-stream-cons: control close throwing behavior.Kaz Kylheku2021-08-076-20/+82
| | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_init): Update registrations of lazy-stream-cons and get-lines with one more optional argument. * lib.c (simple_lazy_stream_func_nt, lazy_stream_func_nt): New static functions. (lazy_stream_cons): Take a new argument, no_throw_close, defaulting it to nil. When calling close_stream directly, pass the inverted value of no_throw_close. Choose the new _nt functions for the lazy list if no_throw_close is true; those functions pass nil as the second argument of close_stream. * lib.h (lazy_stream_cons): Declaration updated. * match.c (v_next_impl, open_data_source, match_fun): Pass down the nothrow value to lazy_stream_cons, or else nil in situations when that is not applicable or there is no such value. Thus the :nothrow feature of v_next will now not only ensure that there is no exception when opening the stream but also when closing it. Unusual situations encountered when the lazy list reads from the stream still throw. * txr.1: Documented.
* doc: document nested do.Kaz Kylheku2021-08-061-0/+55
| | | | * txr.1: Document do being applied to do/op.
* txr: @(eof) takes argument for binding termination status.Kaz Kylheku2021-08-056-22/+114
| | | | | | | | | | | | | | | | | | | | | | | | | | | | We extend the matching context structures to keep track of the underlying stream from which lines are being taken via the lazy list. Then the implementation of the @(eof) directive, when it hits the eof condition, can use this stream to gain access to the termination status. * match.c (match_line_ctx, match_files_ctx): New member, stream. (ml_all): Take stream argument and initialize new member. (h_call, do_match_line): Pass stream argument to h_call. (mf_all, mf_file_data): Take stream argument and initialize new member. (mf_from_ml): Propagate stream from line context to file context. (freeform_prepare, v_next_impl, match_filter, match_fun, extract): Pass stream argument where now needed. (v_eof): Implement termination status binding via the stream stored in the context. (open_data_source): Store stream in match files context. * tests/010/eof-status.txr: New file. * tests/010/eof-status.expected: New file. * Makefile (tst/tests/010/eof-status.ok): -B option for new test. * txr.1: Documented eof directive, argument and all. * stdlib/doc-syms.tl: Updated.
* close-stream: make idemponent.Kaz Kylheku2021-08-043-10/+17
| | | | | | | | | | | | | | | | | | * stream.c (strm_base_init): Add new element to the initializer to initialize the close_result member to nao, indicating that the close operation has not been invoked. (strm_base_mark): Mark the close_result value, if it isn't nao. This is just in case it is a heap object. The structure delegate mechanism opens the possibility that the stream is actually user code that can return anything so we have to be careful. (close_stream): Only call ops->close if close_result is nao, indicating that close had never been called (or possibly that it had been called bu threw an exception) and store the return value in close_result, otherwise return the previously stored value. * stream.h (struct strm_base): New member, close_result. * txr.1: Documented.
* musl: fix missing <sys/time.h>.Kaz Kylheku2021-08-042-2/+7
| | | | | | | | | | | | | | | | Issue peported by Ethan Hawk. Our socket.c module is using struct timeval without including <sys/time.h>, which breaks on musl. * configure: in the select test, let's include <sys/time.h>, and if the test passes, let's set have_sys_time, so that HAVE_SELECT implies HAVE_SYS_TIME. This way code wrapped with HAVE_SELECT doesn't separately have to test for HAVE_SYS_TIME. * socket.c: If HAVE_SYS_TIME is true, then we include <sys/time.h>, independently of HAVE_SELECT. (sock_timeout, sock_load_init): Like the select-based code, code using SO_SNDTIMEO or SO_RCVTIMO also uses timeval, so needs to be wrapped with HAVE_SYS_TIME.
* listener: print prompts in plain mode if stdin is tty.Kaz Kylheku2021-08-032-11/+9
| | | | | | | * linenoise/linenoise.c (linenoise): Force the printing of prompts if the input file descriptor is a tty. * txr.1: Documentation updated.
* listener: print banner only if stdin is a tty.Kaz Kylheku2021-08-031-3/+7
| | | | | | * txr.c (banner): If standard input isn't a tty, bail. Now takes a self argument for the c_int function. (txr_main): Pass self value down to banner.
* listener: prompt feature for plain mode.Kaz Kylheku2021-08-034-2/+36
| | | | | | | | | | | | | | | | | | The :prompt-on command will enable prompting in plain mode. * linenoise/linenoise.c (struct lino_state): New member, show_prompt. (line_enable_noninteractive_prompt): New function. (linenoise): In the plain mode loop, the show_prompt flag is on, show the prompt. For continuation lines, show a condensed prompt, which consists of the suffix of the full prompt, starting on the last non-whitespace character. * linenoise/linenoise.h (lino_enable_noninteractive): Declared. * parser.c (repl): Implement :prompt-on command which enables the above mode. * txr.1: Documented.
* streams: document redundant close-stream.Kaz Kylheku2021-08-021-0/+10
| | | | | * txr.1: Document that if close-stream is applied to a closed stream, then nil is returned without throwing an exception.
* streams: bad argument defaulting in close-stream.Kaz Kylheku2021-08-023-7/+7
| | | | | | | | | | | | | | | * stream.c (stdio_close, pipe_close): Fix throw_on_error argument not being defaulted correctly, so that errors are thrown even when the argument is omitted. * strudel.c (strudel_close): Here, we also must default the argument. The corresponding close method does not have an optional argument; it is mandatory. The documentation is bungled for it, though. * txr.1: Fix documentation of structure delegate streams with regard to the close method. It does not take offs and whence parametrs, but throw-on-error-p, which is mandatory.
* tests: fix undefined variable warning.Kaz Kylheku2021-08-031-1/+3
| | | | | * tests/012/oop.tl: Adjust one recently added test case to eliminate undefined variable warning.
* listener: support multi-line expressions in plain mode.Kaz Kylheku2021-08-012-8/+44
| | | | | | | | | | | | | * linenoise/linenoise.c (linenoise): If we are in noninteractive mode, then do not just read one line and return it. If an enter_callback is defined then keep accumulating lines while the callback indicates incomplete syntax, until EOF occurs or the syntax appears complete. Return the lines glued together, with \n characters replaced by \r, so the line is correctly entered into the history, and the trailing LF obliterated, as usual. * txr.1: Documented new multi-line behavior of plain mode.
* oop: fix infelicity in new* and lnew* macros.Kaz Kylheku2021-07-313-10/+98
| | | | | | | | | | * stdlib/struct.tl (sys:new-expander): If the argument of new* or lnew* is dwim, then treat that as an expression, rather than as a boa-style construction. * tests/012/oop.tl: Tests for new* focusing on this issue. * txr.1: Documented.
* doc: *read-bad-json* fix and doc-syms update.Kaz Kylheku2021-07-312-1/+2
| | | | | | * txr.1: Fix code -> codn. * stdlib/doc-syms.tl: Updated.
* tests: multiple evaluation issue in amb.Kaz Kylheku2021-07-301-2/+2
| | | | | | | | | | | | | | | | This issue doesn't affect the tests. This is for the benefit of someone who happens to be copy-and-pasting the amb implementation from here. * tests/012/cont.tl (amb): This function has an issue in that it calls the continuation (future calculation) and then if that succeeds, it normally returns the value. This means that the future is executed again. In the case of N amb expressions, the successful future is executed 2**N times. What amb must do is this: call the continuation and capture the value. If the value is successful, then that is the master return value; just return that from amb-scope, bypassing the second re-execution of the future.
* tests: longer test for delimited continuations.Kaz Kylheku2021-07-301-0/+10
| | | | | * tests/012/cont.tl: New test case. This aborts prior to recent gc fixes.
* parser: allow trailing commas in json, via opt-in flag.Kaz Kylheku2021-07-296-1769/+1807
| | | | | | | | | | | | | | | | | | | | | | | * parser.c (read_bad_json_s): New symbol variable. (parser_common_init): Propagate value of *read-bad-json* into read_bad_json flag in parser structure. (parser_init): Initialize read_bad_json_s and register the *read-bad-json* dynamic variable. * parser.h (struct parser): New member, read_bad_json. (read_bad_json_s): Declared. * parser.y (json_val): Support an opt_comma symbol just before the closing bracket or brace. (opt_comma): New nonterminal symbol. Recognizes ',' or nothing. Error is flagged if ',' is recognized, and *read-bad-json* is nil. * y.tab.c.shipped: Updated. * tests/010/json.tl: New tests. * txr.1: Documented.
* gc: problem in environment-copying functions.Kaz Kylheku2021-07-291-7/+12
| | | | | | | | | | | | | * eval.c (copy_env, deep_copy_env): These functions are not following a protocol for object construction that is correct under generational GC. They are allocating a new object with make_obj first, and then calling functions to copy the constituent elements to populate into the object with a direct assignment. This direct assignment is wrong; the set macro is required. A better fix, rather than using the set macro, is to copy the constituent parts first, holding them in local variables, then allocate the new object, and finally, without doing any other memory allocating operations, assign the constituent parts into the new object.
* gc: problem in several object copying functions.Kaz Kylheku2021-07-294-13/+16
| | | | | | | | | | | | | | | | | | The functions copy-cons, copy-tree, copy-fun and copy-tnode have a problem. They copy the original object bitwise with a structure assignment, and then make some adjustments. The problem is that this inappropriately copies the object's metadata related to gc, such as its generation number or finalization count. To fix this, we introduce a copy_obj function, which is a companion to make_obj. This performs a shallow copy of an object without incorrectly propagating inappropriate metadata. * gc.c, gc.h (copy_obj): New function. * lib.c (copy_fun, copy_cons, copy_tree): Use copy_obj, instead of make_obj plus structure assignment. * tree.c (copy_tnode): Likewise.
* quips: new one.Kaz Kylheku2021-07-281-0/+1
| | | | * stdlib/quips.tl (sys:%quips%): New entry.
* subtypep: handle struct type objects.Kaz Kylheku2021-07-273-10/+66
| | | | | | | | | | | | | The subtypep function has poor requirements, handling only type symbols. Let's extend it to handle structure type objects. * lib.c (subtypep): In all cases when an argument is considered to be a possible structure symbol, and thus subject to find_struct_type, consider whether it already is a struct type, and just take it as-is. * tests/012/type.tl: New tests. * txr.1: Updated.
* places: remove unnecessary zap_s variable.Paul A. Patience2021-07-272-4/+3
| | | | | | | | | | | | The zap_s variable is a vestige of op_modplace. It must have been missed when op_modplace was removed in commit 209e731429a0fd890ec6d922c1efc6f02d81a032. * eval.c (zap_s): Delete variable. (eval_init): Remove initialization of zap_s. * protsym.c (zap_s): Remove extern variable declaration. (protected_sym): Remove reference to zap_s.
* lib: correct remql's diagnostic name.Paul A. Patience2021-07-271-1/+1
| | | | | * lib.c (remql): Correct the rem_impl call's name argument from "remq" to "remql".
* struct: get rid of pointer typedef.Kaz Kylheku2021-07-272-7/+7
| | | | | | | | * lib.h (slot_cache_t): Typedef removed. (struct sym): Use slot_cache_set_t *. * struct.c (struct_type_finalize, lookup_slot, lookup_static_slot, lookup_static_slot_desc): Likewise.
* Version 267.txr-267Kaz Kylheku2021-07-267-1383/+1442
| | | | | | | | | | | | | | * 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.
* tags: don't escape etag patternsPaul A. Patience2021-07-251-21/+20
| | | | | | | | | | | | | | | | | | | | | | The first field of each etag definition is referred to in the spec as the "pattern", but it is supposed to contain literal text, and therefore no characters within it need be escaped. * tags.tl (escape): Move above tag definition. (tag)[pattern]: Rename to... [line]: ...this. [text]: Update renamed slot. Escape the line here rather than on creation. [etext]: Update renamed slot. (slot-tag)[text]: Update renamed slot. Escape the line here rather than on creation. (orig-tag)[line]: Rename to... [orig-line]: ...this. [text]: Update renamed slot. (get-pos-pat): Rename to... (get-pos-line): ...this. Don't escape the line when returning it. (with-tag-shorthand-macro, toplevel): Rename variables and references to functions in accordance with the above.
* tags: option for qualified identifier tags.Kaz Kylheku2021-07-251-2/+15
| | | | | | | * tags.tl (tags-opts): New q/qual option. (slot-tag make-qual-tag): New method. (toplevel): If qualified tags requested, then augment the list of tags with qualified tags.
* pure-rel-path-p: rewrite without regex.Kaz Kylheku2021-07-221-15/+21
| | | | | | | | * stream.c (volume_name_p): New static function. (plp_regex): Static variable removed. (pure_rel_path_p): Rewrite using lower-level string manipulation, and using volume_name_p instead of a cached regex. (stream_init): Remove reference to plp_regex.
* pure-rel-path-p: add tests.Kaz Kylheku2021-07-221-0/+23
| | | | * tests/018/path.tl: New tests.
* hash: change make_hash interface.Kaz Kylheku2021-07-2215-81/+85
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The make_hash function now takes the hash_weak_opt_t enumeration instead of a pair of flags. * hash.c (do_make_hash): Take enum argument instead of pair of flags. Just store the option; nothing to calculate. (weak_opt_from_flags): New static function. (tweak_hash): Function removed. (make_seeded_hash): Adjust to new do_make_hash interface with help from weak_opt_from_flags. (make_hash, make_eq_hash): Take enum argument instead of pair of flags. (hashv): Calculate hash_weak_opt_t enum from the extracted flags, pass down to make_eq_hash or make_hash. * hash.h (tweak_hash): Declration removed. (make_hash, make_eq_hash): Declarations updated. * eval.c (me_case, expand_switch): Update make_hash calls to new style. (eval_init): Update make_hash calls and get rid of tweak_hash calls. This renders the tweak_hash function unused. * ffi.c (make_ffi_type_enum, ffi_init): Update make_hash calls to new style. * filter.c (make_trie, trie_add, filter_init): Likewise. * lib.c (make_package_common, obj_init, obj_print): Likewise. * lisplib.c (lisplib_init): Likewise. * match.c (dir_tables_init): Likewise. * parser.c (parser_circ_def, repl, parse_init): Likewise. * parser.l (parser_l_init): Likewise. * struct.c (struct_init, get_slot_syms): Likewise. * sysif.c (get_env_hash): Likewise. * lex.yy.c.shipped, y.tab.c.shipped: Updated.
* hash: rename "flags" to "weak options".Kaz Kylheku2021-07-222-16/+16
| | | | | | | | | | | | | | The flags field of hashes isn't really functioning as flags; it's an enumeration whose numeric properties are exploited in one place in the code. * hash.h (enum hash_flags): Rename to enum hash_weak_opt. (hash_flags_t): Renum to hash_weak_opt_t. (tweak_hash): Declaration updated. * hash.c (struct hash): Rename flags member to wkopt. (hash_print_op, hash_mark, do_make_hash, tweak_hash, make_similar_hash, copy_hash, do_weak_tables): Follow renames.
* hash: and-semantics: add missing nuance in marking.Kaz Kylheku2021-07-211-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A weak table with and-semantics expires entries only when both their key and value is unreachable. When this condition is not met, therefore, the hash table generates a reference to both the key and value. This gives rise to a subtlety that must be be correctly handles in the marking phase. * hash.c (hash_mark): When marking an and-semantics table, whenever we find a reachable key or value, we know that the entry is staying. Therefore we mark it: if the key is unreachable, we mark the value and vice versa. This is important because these unreachable objects may be the only references for reaching reach some other objects via one or more weak hash tables. Those secondary objects may spontaneously disappear due to those other hash tables removing their entries. E.g suppose H0 has and-semantics, and some K-V entry in H1 has a reachable K, but unreachable V. Therefore the entry is not eligible for removal, and thus maintains references to K and V. Suppose V happens to be a key in a weak-key hash table H1. If, while marking H0, we do not mark V, then there is a risk that H1 will be processed first during the later weak procesing stage, and H1 will wrongly expire its V entry due to the key V being unreachable. Then when H0 is processed, it will mark V, making it reachable, but too late: the V entry in H1 is already spuriously gone. The main principle at play is that an entry in an and-semantics table strongly holds on to a key if the value is reachable and vice versa. Only if both are simultaneously unreachable does it relinquish its references.
* hash: support both semantics of weak keys + values.Kaz Kylheku2021-07-217-99/+171
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hash tables with weak keys and values now support a choice of both possible semantics: under and-semantics, an entry lapses when both the key and value are unreachable. Under or-semantics, an entry lapses if either the key or value is unreachable. The and-semantics is new. Until TXR 266, only or-semantics was supported. This will be the default: when a hash table is specified as :weak-keys and :weak-vals, it will have or-semantics. The keywords :weak-or and :weak-and specify weak keys and values, with the specific semantics. They are utually exclusive, but tolerate the presence of :weak-keys and :weak-vals. The make-hash function is being extended such that if its leftmost argument, <weak-keys>, is specified as one of the keywords :weak-and or :weak-or, then the hash table will have weak keys and values with the specified semantics, and the <weak-vals> argument is ignored (values are weak even if that argument is false). * eval.c (eval_init): Initially register the top_vb, top_mb, top_smb, special and builtin hashes as ordinary hashes: no weak keys or values. Then use tweak_hash to switch to weak keys+vals with and-semantics. We do it this way because the keywords are not yet initialized; we cannot use them. * hash.h (enum hash_flags, hash_flags_t): Moved to header. Member hash_weak_both renamed to hash_weak_or. New member hash_weak_and. (weak_and_k, weak_or_k): New keyword variables. (hash_print_op): Handle hash_weak_and by printing :weak-and. (hash_mark): Handle hash_weak_and by marking nothing, like hash_weak_or. (do_make_hash): Check first argument against the two new keywords and set flags accordingly. This function is called from eval_init before the keywords have been initialized, in which case weak_keys == weak_and_k is true when both are nil; we watch for that. (tweak_hash): Now returns void and takes a hash_flags_t argument which is simply planted. (do_wak_tables): Implement hash_weak_and case. Remove the compat 266 stuff from hash_weak_or. Compatibility is no longer required since we are not changing the default semantics of hash tables. Phew; that's a load of worry off the plate. (hashv): Parse the two new keywords, validate and provide semantics. (hash_init): Initialize weak_and_k and weak_or_k kewyords. * hash.h (enum hash_flags, hash_flags_t): Moved here now. (weak_and_k, weak_or_k): Declared. * lib.c (compat_fixup): Remove call to parse_compat_fixup. * parser.c (parse_init): Create stream_parser_hash with and-semantics. (parse_compat_fixup): Function removed. * parser.h (parse_compat_fixup): Declaration removed. * txr.1: Hash documentation updated.
* carray: add missing argument type checking.Kaz Kylheku2021-07-211-2/+2
| | | | | | * ffi.c (carray_uint, carray_int): We must use ffi_type_struct_checked here, otherwise we are blindly assuming that the element type is a FFI type.
* compat: fix glaringly broken init-time handling.Kaz Kylheku2021-07-2112-61/+106
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We are doing numerous compat_ver checks in various init functions, to enact alternative symbol registrations. Only problem is, compat_ver is always zero during initialization; it is not set until the -C option is processed in txr_main. Registrations must be fixed up after initialization; that's what the compat_fixup mechanism is for. This is an long-standing problem which affects compatibility operation going back over 150 versions. * arith.c (arith_init): Move compat logic to arith_compat_fixup. (arith_compat_fixup): New function. * arith.h (arith_compat_fixup): Declared. * eval.c (eval_init): Move compat logic to eval_compat_fixup. * ffi.c (ffi_init): Move compat logic to ffi_compat_fixup. (ffi_compat_fixup): New function. * ffi.h (ffi_compat_fixup): Declared. * regex.c (regex_init): Move compat logic to regex_compat_fixup. (regex_compat_fixup): New function. * regex.h (regex_compat_fixup): Declared. * stream.c (stream_init): Move compat logic to stream_compat_fixup. (stream_compat_fixup): New function. * stream.h (stream_compat_fixup): Declared. * struct.c (struct_init): Move compat logic to struct_compat_fixup. (struct_compat_fixup): New function. * struct.h (stream_compat_fixup): Declared. * lib.c (compat_fixup): Call arith_compat_fixup, ffi_compat_fixup, regex_compat_fixup, stream_compat_fixup and struct_compat_fixup.
* parse/eval: use weak-both hash tables.Kaz Kylheku2021-07-206-7/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | This addresses the problem that a4c376979d15323ad729e92e41ba43768e8dc163 tried to fix. * eval.c (eval_init): Make all the top-level binding tables, top_fb, top_vb, top_mb, top_smb, special and builtin, weak-both tables: keys and values are weak. This way, the entries disappear if both key and value are unreachable, even if they refer to each other. (eval_compat_fixup): In 266 or earlier compat mode, weak-both tables don't have the right semantics, so we tweak the tables to weak-key tables. * parser.c (parse_init): Same treatment for stream_parser_hash. We want an entry to disappear from the hash if neither the parser nor the stream are reachable. (parse_compat_fixup): New function. * parser.h (parse_compat_function): Declared. * hash.c, hash.h (tweak_hash): New function. * lib.c (compat_fixup): Call parse_compat_fixup.
* hash: change semantics of weak-both hash tables.Kaz Kylheku2021-07-202-19/+57
| | | | | | | | | | | | | | | | From now on, hash tables with both weak keys and values have dijunctive retention semantics. If either the key or value of an entry is reachable, then the entry stays. This is subject to compatibility. * hash.c (do_weak_tables): Expire an entry if neither the key nor the value is reachable. In 266 or lower compatibility mode, expire an entry if either the key or value is unreachable, like before. * txr.1: Document the change, with compat notes. Add a cautionary note about the referencing issue which defeats weak key or weak value tables.