diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-09-25 23:34:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-09-25 23:34:21 -0700 |
commit | 3d894ee5b065483f749eb7d174daf0d242c54404 (patch) | |
tree | 020cfc5cf7001e32303ad237dbcc03e7b0572171 /tree.h | |
parent | 6d7ae0d677f9c507d15af86cf51f365d6248401d (diff) | |
download | txr-3d894ee5b065483f749eb7d174daf0d242c54404.tar.gz txr-3d894ee5b065483f749eb7d174daf0d242c54404.tar.bz2 txr-3d894ee5b065483f749eb7d174daf0d242c54404.zip |
New data structure: binary search trees.
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.
Diffstat (limited to 'tree.h')
-rw-r--r-- | tree.h | 5 |
1 files changed, 5 insertions, 0 deletions
@@ -25,9 +25,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +extern val tree_s, tree_fun_whitelist_s; + +#define tree_fun_whitelist (deref(lookup_var_l(nil, tree_fun_whitelist_s))) + val tnode(val key, val left, val right); val tnodep(val obj); val left(val node); val right(val node); val key(val node); +val tree(val keys, val key_fn, val less_fn, val equal_fn); void tree_init(void); |