summaryrefslogtreecommitdiffstats
path: root/tree.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-05-11 06:51:16 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-05-11 06:51:16 -0700
commit00e87d26df9f2cd0580b48f92db8ea93a845fbf7 (patch)
tree71552622c8baddcc82c3b7f4ba53f9884e66a952 /tree.c
parent25b5bdc5dfe62037faef8f19c070de434b660aa6 (diff)
downloadtxr-00e87d26df9f2cd0580b48f92db8ea93a845fbf7.tar.gz
txr-00e87d26df9f2cd0580b48f92db8ea93a845fbf7.tar.bz2
txr-00e87d26df9f2cd0580b48f92db8ea93a845fbf7.zip
tree: support indexing and range extraction.
* lib.c (do_generic_funcall): Support tree object invocation with one or two arguments via sub and ref. (sub): Implement for trees via sub_tree. (ref): Implement for trees via tree_lookup. * tree.c (sub_tree): New function. (tree_init): Register sub-tree intrinsic. * tree.h (sub_tree): Declared. * tests/010/tree.tl: New tests. * txr.1: Documented: DWIM bracket syntax on trees, sub and ref support for trees, sub-tree function, * share/txr/stdlib/doc-syms.tl: Regenerated.
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/tree.c b/tree.c
index 191647bd..4f6c2ced 100644
--- a/tree.c
+++ b/tree.c
@@ -922,6 +922,28 @@ val tree_clear(val tree)
return oldsize ? num(oldsize) : nil;
}
+val sub_tree(val tree, val from, val to)
+{
+ val self = lit("sub_tree");
+ struct tree *tr = coerce(struct tree *, cobj_handle(self, tree, tree_s));
+ val iter = if3(missingp(from), tree_begin(tree), tree_begin_at(tree, from));
+ val node, key;
+ list_collect_decl (out, ptail);
+
+ if (missingp(to)) {
+ while ((node = tree_next(iter)))
+ ptail = list_collect(ptail, node->tn.key);
+ } else {
+ while (and2((node = tree_next(iter)),
+ if3(tr->less_fn,
+ funcall2(tr->less_fn, (key = node->tn.key), to),
+ less((key = node->tn.key), to))))
+ ptail = list_collect(ptail, key);
+ }
+
+ return out;
+}
+
void tree_init(void)
{
tree_s = intern(lit("tree"), user_package);
@@ -956,5 +978,6 @@ void tree_init(void)
reg_fun(intern(lit("tree-next"), user_package), func_n1(tree_next));
reg_fun(intern(lit("tree-peek"), user_package), func_n1(tree_peek));
reg_fun(intern(lit("tree-clear"), user_package), func_n1(tree_clear));
+ reg_fun(intern(lit("sub-tree"), user_package), func_n3o(sub_tree, 1));
reg_var(tree_fun_whitelist_s, list(identity_s, equal_s, less_s, nao));
}