From 00e87d26df9f2cd0580b48f92db8ea93a845fbf7 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 11 May 2021 06:51:16 -0700 Subject: 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. --- tree.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tree.c') 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)); } -- cgit v1.2.3