| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
| |
* buf.c (make_owned_buf, buf_str, str_buf): New functions.
(buf_init): buf-str and str-buf intrinsics registered.
* txr.1: Documented.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
| |
* txr.1: Fix two instances of bungled method name meta-syntax.
|
|
|
|
| |
* txr.1: Document that #H() requires the parentheses.
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register copy-tree intrinsic.
* lib.c (copy_tree): New function.
* lib.h (copy_tree): Declared.
* txr.1: Documented.
|
|
|
|
|
| |
* lib.c (copy_alist): Rewrite using list_collect iteration.
endp is used for detecting improper list.
|
|
|
|
|
|
|
|
|
| |
* 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.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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.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.
|
|
|
|
|
|
| |
* txr.1: Documenting #T and #N literals, and the associated
functions and special variable. The yype hierarchy graph is
updated with the new types.
|
|
|
|
|
| |
* txr.1: Add hash-iter into type hierarchy diagram
under [cobj types].
|
|
|
|
| |
* lib.c (middle_pivot): Fix non-conforming indentation.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
* txr.1: the :eq-based keyword and its semantics is
documented, along with its mutual exclusion against the other
two.
|
|
|
|
|
|
|
|
|
|
| |
* 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.l (parser_l_init): Assign an eq-based hash to
form_to_ln_hash.
|
|
|
|
|
| |
* parser.c (parser_circ_def): Instantiate p->circ_ref_hash as
eq-based hash, not eql-based.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* lib.c (populate_obj_hash): Handle tree object.
* parser.c (circ_backpatch): Likewise.
|
|
|
|
|
|
|
| |
* tree.c (tree_clear): New function.
(tree_init): tree-clear intrinsic registered.
* tree.h (tree_clear): Declared.
|
|
|
|
|
|
| |
* tree.c (tree_insert_node): Change to external linkage.
* tree.h (tree_insert_node): Declared.
|
|
|
|
|
| |
* tree.c (tree_insert_node): A node being inserted might not
have null left and right links; we must clear them.
|
|
|
|
|
|
| |
* parser.c (circ_backpatch): Fix neglect to recurse into hash
table's userdata object to look for circle notation
references.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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.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.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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
* tree.c (treep): new function.
(tree_init): Registered treep intrinsic.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (tree_lit_s, tree_construct_s): New symbol variables.
(expand_qquote_rec): Handle sys:tree-lit syntax generated by
quasi-quoted #T notaton by expanding and converting to
sys:tree-constuct call.
(eval_init): Initialize tree_lit_s and tree_construct_s.
* eval.h (tree_lit_s, tree_construct_s): Declared.
* parser.y (tree): Produce sys:tree-lit syntax when #T is
quasi-quoted, and unquotes occur inside it.
* tree.c (tree_construct_fname, tree_construct): New static
functions.
(tree_init): Register sys:tree-construct intrinsic function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (lookup_fun): Check for a lambda expression and
return a faked binding containing the interpreted function.
(do_eval, op_fun): Remove checks for lambda that are now
being done in lookup_fun. In many other places where
lookup_fun is used, we still need lambda checks, like
in the expander.
* share/txr/stdlib/place.tl (sys:get-fun-getter-setter): Take
form argument. Diagnose assignments to lambda, and to unknown
function place syntax.
(defplace symbol-function): Pass sys:*pl-form* to
sys:get-fun-getter-setter as form argument.
* txr.1: fboundp and symbol-function doc updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Oops! We have many instances of compile-error being called
in the old way with a format string as its first agument,
instead of a context argument.
* share/txr/stdlib/ifa.tl (ifa): Take :form argument, pass to
compile-error. Let's call this "fix M".
(sys:if-to-cond): Add form parameter, pass to compile-error.
Let's call this let's call this "fix F".
(conda, condlet): Fix M.
* share/txr/stdlib/place.tl (sys:*pl-form*): New special
variable. We need this in order to communicate the real place
form to the place expander, similarly to how we communicate
the original environment using sys:*pl-env*.
(call-update-expander, call-clobber-expander,
call-delete-expander): Bind sys:*pl-form* to the unexpanded
place.
(shift, lset): Fix M.
(defplace fun): Arrange for value of sys:*pl-form* to be
passed to compile-error. Let's call this "Fix P".
(sys:get-mb): Fix F.
(defplace symbol-macro): Fix P.
(placelet*, placelet): Fix M.
* share/txr/stdlib/txr-case.tl (txr-case-impl): Fix M.
* share/txr/stdlib/with-resources.tl (with-resources): Fix M.
|
|
|
|
|
|
| |
* eval.c (op_fun): Don't cons up a fake fbinding when
processing lambda; just return result of func_interp.
Test for null fbinding consolidated, too.
|
|
|
|
|
|
|
| |
* hash.c (hash_print_op): Replace length 1 put_string calls
with put_char.
* lib.c (obj_print_impl): Likewise.
|
|
|
|
|
|
|
|
| |
* eval.c (lookup_fun); Use iteration to search the nested
environments. Put this code ahead of the global search
so we fall back on it. Also, let's check for a compound
function name first, so we don't search the environments for
this.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (func_get_name): when func_get_name has a nil
function argument and nil env, it falls back on method_name,
which naively searches its space and finds some static slots
with a nil value which is then returned as a method name.
Let's put in a type check that the argument must be a
function. Also, let's drop the recursion in the nested
environment search and switch to iteration, so we don't do
these wasteful sanity checks on multiple re-entries of the
function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adding binary search trees based on the new tnode cell. The
scapegoat algorithm is used, which requires no additional
storage in a cell. In the future we may go to something else,
like red-black trees, and carve out a bit in the tag field
of the cell for the red/black color.
Tree cells store only single key objects, not key/value pairs.
However, which part of the key object is compared is
determined by a custom key function stored in the tree
container. For instance, tree nodes can be cons cells, and car
can be used as the key function; the cdr then stores an
associated value.
Trees have a printed notation
#T(<props> <key>*)
where <props> is a list of up to three items:
<props> ::= ([<key-fn> [<less-fn> [<equal-fn>]]])
key-fn, less-fn and equal-fn are function names.
If they are missing or nil, they default, respectively, to
identity, less and equal.
For security, the printed notation is machine-readable only if
these options are symbols, not lambda expressions.
Furthermore, the symbols must be listed in the special
variable *tree-fun-whitelist*.
* eval.c (less_s): New symbol variable.
(eval_init): Initialize less_s.
* eval.h (less_s): Declard.
* parser.h (grammar): New #T token recognized, mapped to
HASH_T.
* parser.y (HASH_T): New terminal symbol.
(tree): New non-terminal symbol.
(i_expr, n_expr): Add tree to productions.
(fname_helper): New static function.
(yybadtoken): Map HASH_T to "#T".
* protsym.c: Tweaked accidentally; remove.
* tree.c (TREE_DEPTH_MAX): New macro.
(struct tree): New struct type.
(enum tree_iter_state): New enumeration.
(struct tree_iter): New struct type.
(tree_iter_init): New macro.
(tree_s, tree_fun_whitelist_s): New symbol variables.
(tn_size, tn_size_one_child, tn_lookup, tn_find_next,
tn_flatten, tn_build_tree, tr_rebuild,
tr_find_rebuild_scapegoat, tr_insert, tr_lookup, tr_do_delete,
tr_delete, tree_insert_node, tree_insert, tree_lookup_node,
tree_lookup, tree_delete, tree_root, tree_equal_op,
tree_print_op, tree_mark, tree_hash_op): New static functions.
(tree_ops): New static struct.
(tree): New function.
(tree_init): Initialize tree_s and tree_fun_whitelist_s symbol
variables. Register intrinsic functions tree,
tree-insert-node, tree-insert, tree-lookup-node, tree-lookup,
tree-delete, tree-root. Register special variable
*tree-fun-whitelist*.
* tree.h (tree_s, tree_fun_whitelist_s, tree): Declared.
(tree_fun_whitelist): New macro.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Binary search tree nodes are being added as a basic heap data
type. The C type tag is TNOD, and the Lisp type is tnode.
Binary search tree nodes have three elements: a key, a left
child and a right child.
The printed notation is #N(key left right). Quasiquoting
is supported: ^#N(,foo ,bar) but not splicing.
Because tnodes have three elements, they they fit into TXR's
four-word heap cell, not requiring any additional memory
allocation.
These nodes are going to be the basis for a binary search tree
container, which will use the scapegoat tree algorithm for
maintaining balance.
* tree.c, tree.h: New files.
* Makefile (OBJS): Adding tree.o.
* eval.c (expand_qquote_rec): Recurse through tnode cells,
so unquotes work inside #N syntax.
* gc.c (finalize): Add TNOD to no-op case in switch; tnodes
don't require finalization.
(mark_obj): Traverse tnode cell.
* hash.c (equal_hash): Add TNOD case.
* lib.c (tnode_s): New symbol variable.
(seq_kind_tab): New entry for TNOD, mapping to SEQ_NOTSEQ.
(code2type, equal): Handle TNOD.
(obj_init): Initialize tnode_s variable.
(obj_print_impl, populate_obj_hash): Handle TNOD.
(init): Call tree_init function in tree.c.
* lib.h (enum type, type_t): New enumeration TNOD.
(struct tnod): New struct type.
(union obj, obj_t): New union member tn of type struct tnod.
(tnode_s): Declard.
* parserc.c (circ_backpatch): Handle TNOD, so circular
notation works through tnode cells.
* parser.l (grammar): Recognize #N prefix, mapping to
HASH_N token.
* parser.y (HASH_N): New grammar terminal symbol.
(tnode): New nonterminal symbol.
(i_expr, n_expr): Add tnode cases to productions.
(yybadtoken): Map HASH_N to "#N" string.
|
|
|
|
|
|
|
|
|
|
| |
* hash.c (equal_hash): When hashing conses and ranges,
perturb the seed going into the hash for the second element,
rather than hashing it the same way, and then multiplying it.
When hashing the elements of a vector, perturb the seed of
each one by multiplying by the index. For the CHR, NUM, BGNUM,
FLNUM and several types hashed like pointers, we now mix the
seed into the hash.
|
|
|
|
|
|
|
|
| |
* lib.c (equal): Since we have switched on the type of the
left and right argument, we can access the object directly
instead of going through car and cdr. Except that for a lazy
conses, we need at least one such access to force the object
first.
|