mirror of
https://git.sr.ht/~crc_/retroforth
synced 2024-11-16 19:48:56 +01:00
Add Buffer example
FossilOrigin-Name: f66f25fad64e757973afac7ce55f9b31f3eedfb0f8cbbaf6354d75629718d4b2
This commit is contained in:
parent
ef3caab476
commit
e54b603f49
2 changed files with 104 additions and 0 deletions
|
@ -54,6 +54,7 @@
|
|||
|
||||
## Examples
|
||||
|
||||
- add Buffer.forth
|
||||
- add CaptureOutput.forth
|
||||
- add DisplayNames.forth
|
||||
- add KeyValueStore.forth
|
||||
|
|
103
example/Buffer.forth
Normal file
103
example/Buffer.forth
Normal file
|
@ -0,0 +1,103 @@
|
|||
The `buffer:` words are one of the few direct holdovers
|
||||
from RETRO11. I use them frequently, but don't have a
|
||||
good single example or description. So let's rectify
|
||||
that now.
|
||||
|
||||
A buffer is just a linear sequence of memory. These
|
||||
words provide a way to incrementally store or retrieve
|
||||
values from it.
|
||||
|
||||
To begin, create a memory region to use as a buffer.
|
||||
|
||||
~~~
|
||||
'Test d:create #1025 allot
|
||||
~~~
|
||||
|
||||
Then you can set this as the current buffer:
|
||||
|
||||
~~~
|
||||
Test buffer:set
|
||||
~~~
|
||||
|
||||
When a buffer is set, the vocabulary sets an internal
|
||||
index to the first address in it. This will be
|
||||
incremented when you add data and decremented when you
|
||||
remove data.
|
||||
|
||||
Let's add some stuff using `buffer:add`:
|
||||
|
||||
~~~
|
||||
#100 buffer:add
|
||||
#200 buffer:add
|
||||
#300 buffer:add
|
||||
~~~
|
||||
|
||||
And then retreive the values:
|
||||
|
||||
~~~
|
||||
buffer:get n:put nl
|
||||
buffer:get n:put nl
|
||||
buffer:get n:put nl
|
||||
~~~
|
||||
|
||||
You can remove all values using `buffer:empty`:
|
||||
|
||||
~~~
|
||||
#100 buffer:add
|
||||
#200 buffer:add
|
||||
#300 buffer:add
|
||||
buffer:empty
|
||||
~~~
|
||||
|
||||
And ask the buffer how many items it contains:
|
||||
|
||||
~~~
|
||||
buffer:size n:put nl
|
||||
#100 buffer:add
|
||||
#200 buffer:add
|
||||
#300 buffer:add
|
||||
buffer:size n:put nl
|
||||
buffer:empty
|
||||
~~~
|
||||
|
||||
The other functions are `buffer:start`, which returns
|
||||
the address of the buffer, `buffer:end`, which returns
|
||||
the address of the last value, and `buffer:preserve`.
|
||||
The first is easy to demo:
|
||||
|
||||
~~~
|
||||
buffer:start Test eq? n:put nl
|
||||
~~~
|
||||
|
||||
The last one is useful. Only one buffer is ever active
|
||||
at a given time. The `buffer:preserve` combinator lets
|
||||
you execute a word, saving and restoring the current
|
||||
buffer indexes. So the word could assign and use a new
|
||||
buffer and this will reset the previous one after
|
||||
control returns.
|
||||
|
||||
There are a few notes that need to be considered. The
|
||||
preserve combinator saves the start and current index
|
||||
but *not* the contents. If the word you call uses the
|
||||
same buffer, the contents will remain altered.
|
||||
|
||||
Finally, the buffer words have one interesting trait:
|
||||
they store an ASCII NULL after adding each item to the
|
||||
buffer. This lets one use them to build strings easily.
|
||||
|
||||
~~~
|
||||
Test buffer:set
|
||||
$h buffer:add
|
||||
$e buffer:add
|
||||
$l buffer:add
|
||||
$l buffer:add
|
||||
$o buffer:add
|
||||
$, buffer:add
|
||||
#32 buffer:add
|
||||
$w buffer:add
|
||||
$o buffer:add
|
||||
$r buffer:add
|
||||
$l buffer:add
|
||||
$d buffer:add
|
||||
buffer:start s:put nl
|
||||
~~~
|
Loading…
Reference in a new issue