/srcbtree.txt
\ Manage a mapping of "cell" values to another value.
\ Uses a binary tree.
\ A binary tree has a value, and then "<=" and ">" nodes.  If
\  the "<=" node is 0, it is a leaf; the latter node value is
\  the corresponding leaf value.
\ The tree is not self-balancing; well distributed keys should
\  be used.
only extensions definitions

















: (btleaf?) ( a -- bool ) cell+ @ 0= ;                               vandys

\ Look up a key in the tree, return its value plus true, else false
: bt_find ( a tree -- u true | false )
 @ ?dup 0= if 2drop false exit then
 begin
  dup (btleaf?) if
   dup @ rot = if cell+ cell+ @ true else 2drop false then exit then
  2dup @ <= if cell+ else cell+ cell+ then @
  dup 0= if 2drop false exit then
 again ;

\ Create a leaf from the a->u parameters
: (btleaf) ( u a -- ptr ) here -rot , 0 , , ;

\ Tell if the tree pointer points to a non-empty tree
: (btempty?) ( tree -- bool ) @ 0= ;

\ Insert the first leaf
: (1stleaf) ( u a tree -- ) -rot (btleaf) swap ! ;

\ Pick <= or > field based on integer value
: (btselect) ( node d -- a )
 0 <= if cell+ else cell+ cell+ then ;

\ Descend a level in the node hierarchy
: (btdescend) ( u a node -- u a node' )
 2dup @ - (btselect) @ ;

\ Clone a B-tree node
: (btclone) ( node -- node' node )
 here 3 cells allot 2dup 3 cells move swap ;


















\ Insert the a->u mapping onto the provided leaf
: (btspawn) ( u a node -- )
 2dup @ - ?dup 0= if nip cell+ cell+ ! exit then
 >r >r (btleaf) r> ( node1 node R: d )
 (btclone) tuck r> ( node1 node node2 node d )
 0 <= if cell+ cell+ ! cell+ !
 else cell+ ! cell+ cell+ ! then ;

\ Find value "u" under key "a" in the tree starting at "tree"
: bt_insert ( u a tree -- )
 dup (btempty?) if (1stleaf) exit then
 @ begin dup (btleaf?) not while
  (btdescend)
 repeat (btspawn) ;











\ Internal version of tree display, with indentation count
: (.bt) ( node u -- )
 dup spaces
 over (btleaf?) if
  \ Display a leaf
  drop dup @ . ."  ->" cell+ cell+ @ . cr
 else \ Display the label for this node, then recurse for the two sides
  1+ over @ . ." :" cr key drop
  over cell+ @ over recurse
  swap cell+ cell+ @ swap recurse
 then ;

\ Display the binary tree
: .bt ( tree -- ) cr dup (btempty?) if exit then @ 0 (.bt) ;

only