summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* op/do: clean up documentation-implementation problem.Kaz Kylheku2019-10-232-65/+143
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It was reported by astute user vapnik spaknik that the documentation says thing about the do operator which are not actually true in the implementation. I've decided that one of them should be true, and so both implementation and documentation are changing. The documentation claims that (do set x) will produce a function that can be called with one argument; that argument will be assigned to x. That doesn't work, but this commit will make it work. The documentation has this example transformation: (do + foo) -> (lambda rest (+ foo . rest)) that cannot be made to work because do works with macros and special operators to which arguments can't be dynamically applied. This patch will not make the above work; instead the example is corrected. How do is going to work inow is that (do sym ...) syntax in which no implicit variables appear will be equialent to (do sym ... @1). The generated variadic function has one required argument which is implicitly added to the syntax. Obviously, that only works if that positon of the syntax is an evaluated form or place. Values of the -C option equal to 225 or less will restore the old do behavior. * share/txr/stdlib/op.tl (sys:op-expand): Support the new style of do, subject to backward compatibility. A hack is required here. We cannot discover the @1, @2 .. variables in the syntax until we fully expand it. But that code walk requires the syntax to be valid. For instance if (do set x) is specified, with the expectation that it is equivalent to (do set x @1), we cannot process that by code walking (set x). (set x) is invalid syntax. What we do is to *try* expanding it as (set x). If that doesn't work, we add a dummy gensym to the form to produce (set x #:gNNNN) and try expanding that. In that case, rather than adding @1 to the form, we replace the dummy gensym with @1. The algorithm is careful not to accidentally conceal real syntax errors in the form. If the form without the dummy gensym fails to expand, and the one with the dummy gensym expands fine but contains references to implicit parameters (@1, @2, ... @rest), we expand it again without the gensym and allow the error to propagate. Other aspects of this change are fairly trivial. Because the do logic possibly introduces a @1 that doesn't exist, near the end of this function we have to bind another metas variable which has an up-to-date copy of the gens slot. (op-ignerr): New macro; we can't use ignerr because that will create a bootstrapping cycle; ignerr expands to catch, and the catch macro uses do. Wrapping this in eval-only, since we don't need an op-ignerr macro in the compiled image. * txr.1: Documentation revised and updated. Differences between do and op put clarified and put into point form. Bad do examples corrected. Syntax of do now shown as having a required parameter that is an operator. Compat notes added.
* mpi: memory leak in mp_bit.Kaz Kylheku2019-10-221-1/+6
| | | | | | * mpi.c (mp_bit): If the argument is negative, and we have produced a temporary mp_int, we must clear it before returning.
* circle notation: some backpatching optimizations.Kaz Kylheku2019-10-211-6/+13
| | | | | | | * parser.c (circ_backpatch): For hashes and trees, if the count has not changed while traversing the elements, then it means nothing was backpatched: there is no need to do the extra expensive step of rebuilding the hash or tree.
* hash: observe count in eql-based hash.Kaz Kylheku2019-10-211-0/+3
| | | | * hash.c (eql_hash): Decrement count and bail if zero.
* hash: rename hash_rec_limit.Kaz Kylheku2019-10-181-10/+10
| | | | | | | | | | | | | | hash_rec_limit isn't a limit on recursion depth but on the elements traversed. * hash.c (hash_rec_limit): Variable renamed to hash_traversal_limit. (gethash_c, gethash_e, remhash, hash_equal): Use new name. (set_hash_rec_limit): Function renamed to set_hash_traversal_limit. (hash_init): set-hash-rec-limit intrinsic renamed to set-hash-traversal-limit. This function is undocumented, so no backward compatibility is provided.
* hash: get rid of hash_str_limit.Kaz Kylheku2019-10-181-18/+13
| | | | | | | | | | | | | | hash.c (hash_str_limit): Variable removed. (hash_c_str): Take count parameter. Observe the limit and update it. The count is scaled by 4 for strings: four characters for one count. (hash_buf): Likewise. (equal_hash): Pass count to hash_c_str and hash_buf. Use the count to determine how far to force a lazy string for hashing. (set_hash_str_limit): Static function removed. (hash_init): Removed sys:set-hash-str-limit intrinsic. This was used in genman.txr once, but that use was removed a year and a half ago.
* hash: observe count limit for vectors and hash tables.Kaz Kylheku2019-10-181-1/+3
| | | | | | * hash.c (equal_hash): Break out of hashing a vector when the count is exceeded. (hash_hash_op): Likewise for traversing a hash table.
* functions: provide accessors for basic properties.Kaz Kylheku2019-10-184-0/+124
| | | | | | | | | | | | | | * eval.c (eval_init): Register intrinsic functions fun-fixparam-count, fun-optparam-count, fun-variadic. * lib.c (get_param_counts): New static function. (fun_fixparam_count, fun_optparam_count, fun_variadic): New functions. * lib.h (fun_fixparam_count, fun_optparam_count, fun_variadic): Declared. * txr.1: Documented.
* doc: bitfield allocation rules: endiannness.Kaz Kylheku2019-10-171-4/+27
| | | | | * txr.1: Add discussion about endinanness to Bitfield Allocation Rules for completeness.
* compiler: warn on too many lambda args.Kaz Kylheku2019-10-172-0/+4
| | | | | | | | | * share/txr/stdlib/vm-param.tl (%max-lambda-fixed-args%): New symbol macro. * share/txr/stdlib/compiler.tl (compiler comp-lambda): If the nubmer of fixed parameters exceeds %max-lambda-fixed-args%, then issue a warning.
* vm: prevent overflow of fixparam field in function.Kaz Kylheku2019-10-172-11/+22
| | | | | | | | | | | | | Functions can only have 127 fixed parameters; some code ignores this when assigning to the bitfield. * lib.h (FIXPARAM_BITS, FIXPARAM_MAX): New preprocessor symbols. (struct func): Use FIXPARAM_BITS for defining fixparam and optargs bitfields instead of hard-coded 7. * lib.c (func_vm): Sanity check the fixparam and reqags parameters: 0 <= reqargs <= fixparam <= FIXPARAM_MAX.
* doc: grammar fix in datagram streams.Kaz Kylheku2019-10-171-1/+1
| | | | | * txr.1: Subject-verb number agreement; also removing superfluous adverb.
* buffers: new functions buf-str and str-buf.Kaz Kylheku2019-10-172-0/+68
| | | | | | | * buf.c (make_owned_buf, buf_str, str_buf): New functions. (buf_init): buf-str and str-buf intrinsics registered. * txr.1: Documented.
* doc: read-until-match effect on stream position.Kaz Kylheku2019-10-161-0/+23
| | | | | | | * txr.1: Document athat the read-until-match, scan-until-match and count-until-match functions leave the stream position in an unspecified state, since the position returned by seek-stream doesn't take into account push-back characters.
* doc: relocate misplaced buffer functions.Kaz Kylheku2019-10-161-63/+63
| | | | | | * txr.1: The descriptions of file-get-buff, command-get-buf, file-put-buf, file-append-buf and command-put-buf are relocated from FFI area to Buffers where they belong.
* doc: func-get-name formatting.Kaz Kylheku2019-10-161-2/+2
| | | | * txr.1: Fix two instances of bungled method name meta-syntax.
* doc: #H() can't be written #H nil.Kaz Kylheku2019-10-161-1/+8
| | | | * txr.1: Document that #H() requires the parentheses.
* New function: copy-tree.Kaz Kylheku2019-10-164-0/+80
| | | | | | | | | | * eval.c (eval_init): Register copy-tree intrinsic. * lib.c (copy_tree): New function. * lib.h (copy_tree): Declared. * txr.1: Documented.
* copy-alist: no mapcar.Kaz Kylheku2019-10-161-1/+4
| | | | | * lib.c (copy_alist): Rewrite using list_collect iteration. endp is used for detecting improper list.
* copy-cons: more efficient; copies lconses.Kaz Kylheku2019-10-162-8/+34
| | | | | | | | | * lib.c (copy_cons): Rewrite to copy the object in a more low-level way, rather than going through the accessors and constructors. Now copies LCONS as LCONS, including its update function. * txr.1: copy-cons re-documented.
* tree: printing: handle unnamed functions.Kaz Kylheku2019-10-161-3/+7
| | | | | | | * tree.c (tree): If the tree abstraction functions don't have a name, then use the functions themselves as the names, rather than nil. Otherwise the printed representation of the tree will look like it has the default abstraction functions.
* tree: copy-search-tree function.Kaz Kylheku2019-10-164-0/+49
| | | | | | | | | | | | | * lib.c (copy): Handle tree objects via copy_search_tree. * tree.c (deep_copy_tnode): New static function. (copy_search_tree): New function. (tree_init): copy-search-tree intrinsic registered. * tree.h (copy_search_tree): Declared. * txr.1: Documented copy-search-tree, and copy function's use thereof.
* tree: node set functions and syntactic places.Kaz Kylheku2019-10-165-1/+98
| | | | | | | | | | | | | | | | | * lisplib.c (defset_set_entries): Autoload entries for left, right and key. * share/txr/stdlib/defset.tl (left, right, key): New simple-form defsets. * tree.c (set_left, set_right, set_key): New functions. (tree_init): Register intrinsics set-left, set-right and set-key. * tree.h (set_left, set_right, set_key): Declared. * txr.1: key, left and right classified as accessors. Documented set-key, set-left and set-right.
* tree: introduce copy-tnode.Kaz Kylheku2019-10-164-0/+30
| | | | | | | | | | | | * lib.c (copy): Handle TNOD casee via copy_tnode. * tree.c (copy_tnode): New function. (tree_init): copy-tnode intrinsic registered. * tree.h (copy_tnode): Declared. * txr.1: copy function documented as handling tnode type via copy-tnode. That function is documented.
* tree: api: harmonize deletion with insertion.Kaz Kylheku2019-10-152-5/+39
| | | | | | | | | * tree.c (tree_delete): Renamed to tree_delete_node. (tree_delete): New function which returns element rather than node. (tree_root): Registered tree-delete-node intrinsic. * txr.1: Documented.
* doc: trees and tree nodes documented.Kaz Kylheku2019-10-151-0/+562
| | | | | | * txr.1: Documenting #T and #N literals, and the associated functions and special variable. The yype hierarchy graph is updated with the new types.
* doc: hash-iter missing in diagram.Kaz Kylheku2019-10-151-0/+2
| | | | | * txr.1: Add hash-iter into type hierarchy diagram under [cobj types].
* lib: middle_pivot: whitespace fix.Kaz Kylheku2019-10-151-4/+4
| | | | * lib.c (middle_pivot): Fix non-conforming indentation.
* eval: bugfix: don't pass eval env to macroexpand.Kaz Kylheku2019-10-131-1/+1
| | | | | | | * eval.c (eval_intrinsic): macroexpand must be called with the nil environment. If we had a macro env parameter, we could pass that. In any case, we mustn't pass an eval environment to the expander.
* hash: optimize vector access.Kaz Kylheku2019-10-121-22/+18
| | | | | | | | | | | | We use direct access instead of going through vecref/vecref_l. As a result of this change, I measured an 8% speedup in "make retest"! I'm also seeing a more than 10% speedup in "make" after "make clean-tlo" (i.e. recompiling the Lisp library). * hash.c (hash_mark, hash_grow, copy_hash, gethash_c, gethash_e, remhash, hash_next, hash_peek, do_weak_tables): Access the table directly.
* hash: use ucnum for hash values everywhere.Kaz Kylheku2019-10-122-12/+12
| | | | | | | | | | | | | | | | | | | One consequence of this is that we no longer pass negative values to vecref; that functon was protecting us from the consequences of this signed/unsigned mixup, at the cost of cyles. * hash.c (struct hash_ops): hash parameter in assoc_fun and acons_new_c_fun pointers changes from cnum to ucnum. (hash_assoc, hash_assql, hash_assq): hash parameter changes to ucnum. (hash_acons_new_c, hash_aconsql_new_c, hash_aconsq_new_c): Likewise. (gethash_c, gethash_e, remhash): Variable which captures the output of the hashing function is now ucnum instead of cnum. * lib.h (struct cons_hash_entry): Member hash changes from cnum to ucnum.
* doc: document :eq-based.Kaz Kylheku2019-10-111-12/+17
| | | | | | * txr.1: the :eq-based keyword and its semantics is documented, along with its mutual exclusion against the other two.
* hash: strengthen type mutual exclusion check.Kaz Kylheku2019-10-111-8/+13
| | | | | | | | | | * hash.c (equal_based_p): Take additional argument eq indicating that :eq-based has been specified. Check all three exclusive combinations. (hashv): Call equal_based_p unconditionally, even when :eq-based is specified and we don't use this function's return value so we benefit from that function's exclusion check. Pass the eq boolean, as required.
* parser: use eq-based hash for source location info.Kaz Kylheku2019-10-111-1/+1
| | | | | * parser.l (parser_l_init): Assign an eq-based hash to form_to_ln_hash.
* parser: use eq-based hash for circular notation.Kaz Kylheku2019-10-111-1/+1
| | | | | * parser.c (parser_circ_def): Instantiate p->circ_ref_hash as eq-based hash, not eql-based.
* printer: obj_hash must be eq-based.Kaz Kylheku2019-10-111-2/+2
| | | | | | | | | The printer must use an eq-based hash table for detecting circularity, otherwise it blows up on circular range objects. * lib.c (obj_print): instantiate ctx->obj_hash as an eq-based hash table, not eql-based.
* expander: origin_hash must be eq-based.Kaz Kylheku2019-10-111-1/+1
| | | | | | | * eval.c (eval_init): Initialize origin_hash as eq-based hash table, not eql-based. The main culprit are range #R(x y) objects. eql equality recurses over these, and if it encounters a circular one like #R(#1# #1#), it crashes.
* hash: implement :eq-based.Kaz Kylheku2019-10-112-8/+120
| | | | | | | | | | | | | | | | | | | | | We need eq based hash tables to fix a problem in *print-circle*. * hash.c (enum hash_type, hash_type_t): New enum type. (eq_based_k): New keyword variable. (eq_hash, eq_hash_op): New static functions. (hash_print_op): Ensure we print eq-based hashes with the correct keyword. (hash_assq, hash_aconsq_new_c): New static functions. (hash_eq_ops): New static structure. (do_make_hash): New function, made from previous contents of make_seeded_hash. (make_seeded_hash): Wrapper around do_make_hash now. (make_eq_hash): New function. (hashv): Parse out :eq-based argument. Use make_eq_hash if it is present. (hash_init): Initialize eq_based_k. * hash.h (eq_based_k, make_eq_hash): Declared.
* sort: remove obsolete comments.Kaz Kylheku2019-10-081-10/+1
| | | | | | * lib.c (sort_list, sort): Remove comments about dangerous mutation; these pertain to some explicit logic which existed in previous versions of the code to handle those situations.
* tree: circular notation support.Kaz Kylheku2019-10-072-0/+30
| | | | | | * lib.c (populate_obj_hash): Handle tree object. * parser.c (circ_backpatch): Likewise.
* tree: add tree-clear function.Kaz Kylheku2019-10-072-0/+12
| | | | | | | * tree.c (tree_clear): New function. (tree_init): tree-clear intrinsic registered. * tree.h (tree_clear): Declared.
* tree: make node insertion external.Kaz Kylheku2019-10-072-1/+2
| | | | | | * tree.c (tree_insert_node): Change to external linkage. * tree.h (tree_insert_node): Declared.
* tree: insert must clear left/right links.Kaz Kylheku2019-10-071-0/+3
| | | | | * tree.c (tree_insert_node): A node being inserted might not have null left and right links; we must clear them.
* circle notation: bugfix for hash_userdata.Kaz Kylheku2019-10-071-0/+3
| | | | | | * parser.c (circ_backpatch): Fix neglect to recurse into hash table's userdata object to look for circle notation references.
* op: new features for anonymous recursion.Kaz Kylheku2019-10-032-40/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | Within the op syntax, the new implicit variable @rec now refers to the function itself. There is also @(rec ...) for calling the function through a function binding. For instance, here is Fibonacci: (do if (> @1 1) (+ @(rec (pred @1)) @(rec (ppred @1))) 1) * share/txr/stdlib/op.tl (sys:op-ctx): New slots rec and recvar. (sys:op-rec-p, sys:op-ensure-rec): New functions. (sys:op-alpha-rename): Check for the new syntaxes and translate to appropriate gensymed expressions, while updating the context structure, so the expander is informed about the @rec or @(rec ...) activity in the expression. (sys:op-expand): Check whether @rec or @(rec ...) has been used in the expression, and generate the necessary variants to support it. We need to bind the lambda to a recursive binding using the same mechanism that labels uses, and possibly to bind the gensym underneat @rec to the value of that function binding. * txr.1: op documentation extended to cover the new feature, plus some wording improvements.
* symbol-function: don't break existing compiled code.Kaz Kylheku2019-10-031-2/+2
| | | | | | | | | | | | | | | | | When a symbol-function form is used as a syntactic place, the generated code makes a run-time call to sys:get-fun-getter-setter. A recent commit changed the interface of this function, which means that such code which has been previously comipled (or somehow retained in macro-expanded form) will break. * share/txr/stdlib/place.tl (sys:get-fun-setter-getter): Change the interface so it's backward compatible with the old one: the first argument is the symbol, like before, and thanks to optional arguments, it can be called with just that argument. (defplace symbol-function): Generate code to call sys:get-fun-setter-getter accordingly.
* tree: tree iterators.Kaz Kylheku2019-10-032-1/+56
| | | | | | | | | | | | * tree.c (struct tree_diter): New struct type. (tree_iter_s): New symbol variable. (tree_iter_mark): New static function. (tree_iter_ops): New static struct. (tree_begin, tree_next): New functions. (tree_init): Initialize tree_iter_s; register tree-begin and tree-next intrinsics. * tree.h (tree_begin, tree_next): Declared.
* tree: bug in key handling in insertion.Kaz Kylheku2019-10-011-16/+17
| | | | | | | | | | | | | * tree.c (tr_insert): We must apply the key_fn to the key of the node which we are inserting, not only to the tree node being searched. This is different from delete, where the key argument is just the key value to be searched for, not a key object from which the key function extracts the key value. Variable naming is hereby adjusted: let's use tr_key for the key from the tree, and tn_key for the key extracted from the argument node. (tn_lookup, tr_delete): Rename the tn_key local variable to tr_key, for consistency with the naming inside tr_insert.
* tree: crash when root is to be replaced.Kaz Kylheku2019-10-011-4/+9
| | | | | | | | * tree.c (tr_insert): When the inserted key matches the root node, then there is nothing in ti->path and ti->depth is zero. We are accessing ti->path[-1] to get a root node. We must test for zero depth and install the new node as the tree root in that case.
* safety: fix type tests that code can subvert.Kaz Kylheku2019-09-307-12/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch fixes numerous instances of a safety hole which involves the type of a COBJ object being tested to be of a given class using logic that can be subverted by the definition of a like-named struct. Specifically logic like (typeof(obj) == hash_s) is broken, because if a struct type called hash is defined, then the test will yield true for instances of that struct type. Those instances can then be passed into code that only works on COBJ hashes, and relies on this test to reject invalid objects. * ffi.c (make_carray): Replace fragile test with strong one, using new cobjclassp function. * hash.c (hashp): Likewise. * lib.c (class_check): The expression used here for the type test moves into the new function cobjclassp and so is replaced by a call to that function. (cobjclassp): New function. * lib.h (cobjclassp): Declared. * rand.c (random_state_p): Replace fragile test using cobjclassp. * regex.c (char_set_compile): Replace fragile typeof tests for character type with is_chr. (reg_derivative, regexp): Replace fragile test with cobjclassp. * struct.c (struct_type_p): Replace fragile test with cobjclassp.