# Key-Value tables

The unit at [mem/kv.fs] provides key-value tables, an efficient way to associate
a value to a key for the purpose of looking up that value later, through the
key.

Both values and keys are 32-bit values.

A KV table has this structure:

* A 32-bit entry count
* <count> key elements
* <count> value elements

This means that "idx" can be used to search keys, which gives us the index at
which the associated value lives.

At the moment, keys are unsorted, but we can very much imagine the same lookup
table being sorted and allowing a bisect algorithm to speed up the search.

## Executable lookup tables

This unit also provide semantics that are very similar to those of [lib/wordtbl]
for values that are execution tokens.

## Example usage

  create mytbl 1 42 2 54 3 128 kvtbl,
  1 kv@# . \ prints 42
  2 kv@# . \ prints 54
  4 kv@# \ aborts with error

  kvtbl[
  'a' :> 42 . ;
  'b' ' anotherword
  'c' :> 54 . ;
  'd' over \ low-tech way to bind multiple values to the same word
  ]kvbl mytbl

  mytbl 'd' ?kvexec . \ prints 54, then 1
  mytbl 'z' ?kvexec . \ prints 0 and calls nothing

## API

kvtbl, ( ... n -- )
  Write a KV table with n elements in it. Elements are present in PS in the
  forms of pairs, intertwined. For example, a PS ( 1 2 3 4 2 ) will generate a
  table with 2 entries keyed 3 and 1 to values 4 and 2, respectively.

kv@ ( tbl key -- ?val f )
  Look up for "key" in "tbl". If found, f=1 and "val" is the associated value.
  Otherwise, f=0 and "val" is absent.

kv@# ( key tbl -- val )
  Perform a lookup and abort with error if not found.

kv@, ( -- notfoundjmp )
  Compile a [doc/hal] lookup of W into table where A points to. The codepath
  directly following the word is the one where key is found. W contains the
  associated value. "notfoundjmp" is a forward jump that must point to the
  "not found" code path.

kvtbl[ ( -- )
  Create a new word table named "name" and write elements accumulated since the
  previous "wordtbl[" call to that table.

]kvtbl ( ... "name" -- )
  Creates a lookup table "name" and write accumulated pairs on PS to that table.

?kvexec ( tbl val -- f )
  Look up "val" in lookup table "tbl". If found, execute the associated XT and
  yield f=1. Otherwise, f=0.
