summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* hash: remove unnecessary tests in weak processing.Kaz Kylheku2021-07-201-4/+3
| | | | | | * hash.c (do_weak_tables): Do not test hash entries for reachability, only keys and values. This is not worth doing and possibly adds cycles.
* hash: fix possibly incorrect counts in weak processing.Kaz Kylheku2021-07-201-16/+11
| | | | | | | * hash.c (do_weak_tables): Iterate to the end of each chain, not quitting early when a reachable tail is found. This has the effect that we will always count the nodes properly. Some common code is factored out of the switch also.
* hash: revert bad fix in weak processing.Kaz Kylheku2021-07-202-20/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit reverts the April 11, 2020 commit a4c376979d15323ad729e92e41ba43768e8dc163, subject line "hash: bugfix: spurious retention in weak processing". That commit is a regression. This revert requires a follow-up; the commit was trying to fix an issue which now reappears. It will have to be fixed differently. The regression is that in a situation in which data is referenced through two or more dependent weak tables, entries that are reachable can spontaneously disappear from downstream tables. Suppose H0 and H1 are weak-key tables. Suppose the program holds a datum K0, which is the only reference through which D1 is reached, in the following chain: K0 -> [H0] -> K1 -> [H1] -> D1 K0 is a key in hash table H0, which has weak keys. The the associated value K1 is a key in H1, which then references D1. H0 holds the only reference to K1, and H1 holds the only reference to D1. During the first GC marking phase, because we do not mark any part of a table which has weak keys, when we process H0 we do not mark the value K1. Thus K1 looks unreachable. In the second weak hash processing pass, because K1 was treated as unreachable, the <K1, D1> entry in H1 is incorrectly expired. This issue affects TXR's origin_hash and form_to_ln_hash, which are in this relationship. The problem was uncovered in recent tags.tl work, manifesting as a spurious disappearance of line number info when processing .txr files. The line number info disappeared for entries which were traced through the origin_hash via the macro-ancestor function (see the unexpand function in tags.tl). * hash.c (hash_mark): Only skip marking tables that have both weak keys and values. For weak key tables, mark all the values and vice versa: for weak value tables, mark the keys. * txr.1: Text resembling original text restored.
* op: set nested flag in correct context.Kaz Kylheku2021-07-192-10/+31
| | | | | | | | | | | | * stdlib/op.tl (sys:op-meta-p): Return an extended Boolean value: a true result is an integer indicating the depth of the variable. For instance @1 is depth 0, @@1 is depth 1 and so on. (sys:find-parent): New function. (sys:op-alpha-rename): When processing a nested meta, do not set the nested flag in the immediate parent. Use find-parent to go up to the correct level to which the meta belongs and set the flag there. * tests/012/op.tl: New test cases which depend on this.
* op: rename argument for consistency.Kaz Kylheku2021-07-191-2/+2
| | | | | | * stdlib/op.tl (sys:op-meta-p): Rename expr argument to exp. The symbol is not causing an issue here, but it's good to rename it for consistency with sys:op-rec-p and to thwart future problems.
* op: consolidate testing for @rec/@(rec ...)Kaz Kylheku2021-07-191-6/+6
| | | | | | | | | * stdlib/op.tl (sys:op-rec-p): Test for both the variable @rec and the expresson @(rec ...). Also, the expr argument of the function is renamed to exp because it causes a problem, due to that symbol, sys:expr, being the meta indicator. (sys:op-ensure-rec): Remove one test for (sys:var usr:rec), since sys:op-rec-p does it. Convert one equal-test to a call to sys:op-rec-p.
* op: fix bug in do.Kaz Kylheku2021-07-192-32/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The June 30 09e70c914ca83b5c7405aa633864db49f27efa05, subject "op: refactor do handling", introduced a regression breaking the tags.tl program. An implicit argument gets inserted twice: [[(do op list @1)] 'x] -> (x x) ;; incorrect/weird This was spotted by Paul A. Patience while working on extending tags.tl for Emacs. It's not exactly a regression because the original behavior is not documented or tested, and has issues; we simply cannot roll back the commit; a proper fix is required. How the above call is now supposed to work is that: - the @1 parameter belongs to the op, not to the do. - the do therefore has no explicitly given parameters of its own. - therefore the do inserts its parameter. In other words (do op list @1) is formally equivalent to (do op list @1 @@1). Both levels of function indirection require an argument: [[(do op list @1) 'x] 'y] -> (y x) [[(do op list @1 @@1) 'x] 'y] -> (y x) * stdlib/op.tl (sys:op-ctx): The structure gets a new slot, nested, which is a flag indicating whether unprocessed nested metas occur. This is critically needed because the sys:op-alpha-rename passes which are called with do-nested-metas being false do not insert nested metas into the gens list; they transform them and leave them in the syntax. Yet we must make decisions based on their presence. Conretely, we must be able to tell that (do op list @@1) has a meta against the outer (do ...), while we are just processing the do. (sys:op-alpha-rename): When replacing a nested meta syntax with the macro invocation, we set the nested flag of the parent context true. (sys:op-expand): Bring back the do-gen; we need it. We cannot simply insert @1 into the syntax, because that is not lexically transparent. If we add @1 to (do op ...) then that @1 is interpreted as belonging to the op, not to the do. We must also check the new Boolean flag nested to properly detect whether we have metas, including unexpanded nested metas. * tests/012/op.tl: New test cases combining (do op ...).
* tags: add support for etags format.Paul A. Patience2021-07-181-21/+82
| | | | | | | | | | | | | | | | | | | | | * tags.tl (etag-sec-start, etag-pat-end, etag-name-end): New variables. (tags-opts): Improve --help option's help message. Add -o/--output and -e/--emacs options. (tag): Add linum and byte slots. Add etext method. (file-tag): Initialize type slot to "F", and use it in the text method. (get-pat): Rename to... (get-pos-pat): ...this, and return the line number and byte offset in addition to the escaped line. (with-tag-shorthand-macro): Initialize linum and byte slots. Remove a needless splice (of the get-pat/get-pos-pat calls). (collect-tags-tl, collect-tags-txr): Add clarifying comments. (write-tagfile): Make use of new -o/--output option. (write-etagfile): New function. (toplevel): Set a default value for o.output if -o/--output is empty or missing. Disallow combination of --emacs and --merge. Remove unused variable have-arv. Fix double @1 appearing in calls to fnmatch from excf. Call write-etagfile instead of write-tagfile if --emacs was provided.
* doc: reproducible PDF.Kaz Kylheku2021-07-172-0/+23
| | | | | | | * Makefile (txr-manpage.pdf): If SOURCE_DATE_EPOCH exists, then run pdf-clobber-stamps.tl. * pdf-clobber-stamps.tl: New file.
* abs-path-p: rewrite in lower-level C.Kaz Kylheku2021-07-151-23/+34
| | | | | | | | | * stream.c (ap_regex): Static variable removed. (volume_prefix_p): New function. (abs_path_p, portable_abs_path_p): Get wchar_t * string from path and manipulate using C idioms. Use volume_prefix_p function for testing for drive letter or UNC prefix. (stream_init): Remove reference to ap_regex.
* paths: new tests.Kaz Kylheku2021-07-151-0/+46
| | | | | * tests/018/path.tl: test coverage for abs-path-p and portable-abs-path-p.
* lib: default_arg_strict becomes macro.Kaz Kylheku2021-07-141-4/+1
| | | | | | | | | | | * lib.h (default_arg_strict): Inline function converted to macro, so that we can suppress the evaluation of the default expression if it is not required. The default_arg_strict idiom is being used all over the stream library now. The common default value expressions like std_out are macros that access the dynamic variable by symbol. We don't want to be wastefully doing that on each stream operation, whether or not a stream argument has been supplied.
* build: recompile txr.c if build_id changes.Kaz Kylheku2021-07-141-2/+9
| | | | | | | | | | | | | | | | | | With this change, it is possible to make build_id=abcd to rebuild TXR with the given build ID. Any changes in the value of a dynamic, git-generated build_id will likewise trigger a rebuild. * Makefile (old_build_id): New variable. We read the old build ID from a file called .build_id in the build directory. If it differs from the current expanded ID, build_id_exp, we remove the object files affected by build_id. In all cases, we then write the current build ID into the .build_id file. (clean, distclean): Remove .build_id.
* sysif: create rlim struct even without HAVE_RLIM.Kaz Kylheku2021-07-141-3/+1
| | | | | | | | | | The reason for this change is that we don't want syntax like #S(rlim cur 0 max 0) to fail to read in a build of TXR that happens not to have detected getrlimit. * sysif.c (rlim_s, cur_s, max_s, rlim_st): Define variables unconditionally. (sysif_init): Initialize variables unconditionally.
* tests: fix stack overflow test case for old gmake.Kaz Kylheku2021-07-141-2/+7
| | | | | | | | | | | | | | | * tests/012/stack.tl: The (if stack-limited ...) test is not correct because even if gerlimit indicates an unlimited stack, we impose a defualt limit, and so (get-stack-limit) returns a an integer value. The idea here was to try to skip this test case when the stack usage is unlmited, which happens under older versions of GNU make, before posix_spawn was introduced. Instead, let's execute this test case only if we have setrlimit. In the forked child, we try to impose a small stack limit that will give use the stack overflow crash we are testing for. The objective of the test case is to validate that when (set-stack-limit 0) is called, the child will abort due to a signal, rather than (recur) returning :so.
* doc: warm-up-period argument of make-random-state.Kaz Kylheku2021-07-131-7/+14
| | | | | | * txr.1: Add missing requirement: warm-up is also not performed if make-random-state is a vector. Improve the wording overall.
* rand: support buffers as random seeds.Kaz Kylheku2021-07-133-6/+129
| | | | | | | | | * rand.c (make_random_state): Recognize buffer object as sources of bits for seeding. * tests/013/rand.tl: New file. * txr.1: Documented.
* rand: remove unnecessary type check.Kaz Kylheku2021-07-131-2/+1
| | | | | | * rand.c (make_random_state): We dn't have to use cobj_handle here because the object isn't an argument; we just instantiated in the same scope, with the correct type.
* New functions: getrlimit, setrlimit.Kaz Kylheku2021-07-134-1/+170
| | | | | | | | | | | | | | | | * stdlib/doc-syms.tl: Updated. * sysif.c (rlim_s, cur_s, max_s): New symbol variables. (rlim_st): New variable. (getrlimit_wrap, setrlimit_wrap): New functions. (sysif_init): gc-protect rlim-st. Initialize symbol vsariables. Create rlim struct type. Register getrlimit and setrlimit intrinsics. Register variables rlim-saved-max, rlim-saved-cur, rlim-infinity, rlimit-core, rlimit-cpu, rlimit-data, rlimit-fsize, rlimit-nofile, rlimit-stack and rlimit-as. * txr.1: Documented under new Unix Resource Limits section.
* sysif: bug: bogosity in protect call.Kaz Kylheku2021-07-131-1/+1
| | | | | * sysif.c (sysif_init): The address of dirent_st must be registered with protect, not the value.