\ 4tH library - Key/value leaves - Copyright 2015 J.L. Bezemer
\ You can redistribute this file and/or modify it under
\ the terms of the GNU General Public License

[UNDEFINED] l.new    [IF]
[UNDEFINED] allocate [IF] include lib/memcell.4th  [THEN]
[UNDEFINED] NULL     [IF] include lib/constant.4th [THEN]
\ include lib/anstools.4th

struct                                 \ structure of a key/value pair
  field: (key)                         \ the key
  field: (val)                         \ the value
  field: (lnk)                         \ link to the next key/value pair
end-struct (/leaf)                     \ size of a leaf structure
                                       ( -- leaf)
: l.new (/leaf) allocate abort" Cannot create key/value" ;
: l.next -> (lnk) @ ;                  ( leaf1 -- leaf2)
: l.key -> (key) @ ;                   ( leaf -- key)
: l.get -> (val) @ ;                   ( leaf -- value)
: l.put -> (val) ! ;                   ( value leaf --)
: l.last begin dup @ NULL <> while @ -> (lnk) repeat ;
                                       ( link1 -- link2)
: l.append                             ( value key link --)
  l.new >r l.last r@ swap ! r@ -> (key) ! r@ l.put NULL r> -> (lnk) !
;                                      \ find the last entry and append
                                       \ find the link pointing to the key leaf
: l.before                             ( key link1 -- link2)
  begin dup @ NULL <> while over over @ l.key <> while @ -> (lnk) repeat nip
;
                                       \ find a key, true if found
: l.find l.before @ dup NULL <> ;      ( key link -- leaf f)
                                       \ delete a key, true if not found
: l.delete                             ( key link -- f)
  l.before dup @ NULL = dup >r
  if drop else dup @ dup l.next rot ! free abort" Cannot free key/value" then
  r>
;                                      \ insert a leaf at this link
                                       ( value key link --)
: l.insert dup >r @ l.new dup >r -> (lnk) ! r@ -> (key) ! r@ l.put r> r> ! ;

[DEFINED] 4TH# [IF]
  hide (key)
  hide (val)
  hide (lnk)
  hide (/leaf)
[THEN]
[THEN]
