unu: simple, literate source files
Developed for use with RetroForth
and Parable, Unu is a
simple format allowing mixing of code, commentary, and tests within
a source file. The format does not support "out of order" structuring.
format
Source files are either ASCII or UTF-8.
Code blocks are extracted from fenced regions that begin and end with
three tilde (~) characters on a line by themselves. These must start
in the first column.
Test blocks are just like code blocks, but use backticks (`) instead
of tildes.
Anything outside a code or test block will be ignored.
downloads
unu in c (in unu)
unu in c
unu in python
unu in retro
example
# A Key-Value Data Store
This implements a key-value data store for RETRO. It's not an
optimal solution, but works well enough for smaller data sets.
A store is setup as a linked list with three values:
0 pointer to previous entry
1 pointer to key (string)
2 pointer to value (string) or value (numeric)
This begins with words to access these fields.
~~~
:kv:link (D-a) ;
:kv:name (D-a) n:inc ;
:kv:value (D-a) #2 + ;
~~~
Next is a word to make a new store. I create a dummy entry
named `(nil)` as the root.
~~
:kv:new (s-) d:create here n:inc , #0 , '(nil) , #0 , ;
~~
Searching the store for an entry is next. This is very inefficient
due to the use of `reorder`. If the performance becomes an issue I
will revisit it later.
~~~
{{
:match? (sD-sf) kv:name fetch over s:eq? ;
:update (abc-cbc) 'abc 'cbc reorder ;
:seek (nsD-ns)
repeat fetch 0; &match? sip swap &update if again ;
---reveal---
:kv:lookup (sD-a) #0 'abc 'cab reorder seek drop ;
}}
~~~
To add or change an entry, I provide `kv:set`. This is even
more inefficient as it scans the store twice when setting an
existing entry.
This could be improved:
- only scan once
- factor out the update and add entry actions
~~~
:kv:update-entry (vsD-) kv:lookup kv:value store ;
:kv:add-entry (vsD-) here over [ [ fetch , , , ] dip ] dip store ;
:kv:set (vsD-)
dup-pair kv:lookup n:-zero?
[ kv:update-entry ] [ kv:add-entry ] choose ;
~~~
The last word is `kv:get`, which returns the contents of the
`kv:value` field.
~~~
:kv:get (sD-v)
kv:lookup dup 0; drop kv:value fetch ;
~~~
And some tests:
```
'Test kv:new
#1000 'FOO Test kv:set
#1500 'BAR Test kv:set
#4000 'FOOBAR Test kv:set
'FOOBAR Test kv:get n:put nl
#5000 'FOOBAR Test kv:set
'FOOBAR Test kv:get n:put nl
```
other notes
The name Unu comes from the Maori language, where it means:
(verb) (-hia) pull out, withdraw, draw out, extract.
Taken from https://maoridictionary.co.nz/