1# Working With a Buffer 2 3RETRO provides words for operating on a linear memory area. 4This can be useful in building strings or custom data 5structures. 6 7## Namespace 8 9Words operating on the buffer are kept in the `buffer:` 10namespace. 11 12## Implementation 13 14A buffer is a linear sequence of memory. The buffer words 15provide a means of incrementally storing and retrieving 16values from it. 17 18The buffer words keep track of the start and end of the 19buffer. They also ensure that an `ASCII:NULL` is written 20after the last value, which make using them for string 21data easy. 22 23## Limitations 24 25Only one buffer can be active at a time. RETRO provides a 26`buffer:preserve` combinator to allow using a second one 27before returning to the prior one. 28 29## Set The Active Buffer 30 31To set a buffer as the active one use `buffer:set`. This takes 32an address. 33 34The buffer will be assumed to be empty. The initial value will 35be set to ASCII:NULL. 36 37## Add Value 38 39Use `buffer:add` to append a value to the buffer. This takes 40a single value and will also add an ASCII:NULL after the end 41of the buffer. 42 43## Fetch Last Value 44 45To return the last value in the buffer you can use `buffer:get`. 46This removes the value and sets an ASCII:NULL in the memory 47location the returned value occupied. 48 49## Get Data About The Buffer 50 51RETRO provides `buffer:start` to get the initial address in 52the buffer, `buffer:end` to get the last address (ignoring the 53ASCII:NULL), and `buffer:size` to return the number of values 54in the buffer. 55 56## Reset 57 58You can reset a buffer to the empty state using `buffer:empty`. 59 60## Example 61 62To begin, create a memory region to use as a buffer. 63 64``` 65'Test d:create #1025 allot 66``` 67 68Then you can set this as the current buffer: 69 70``` 71&Test buffer:set 72``` 73 74When a buffer is set, the vocabulary sets an internal 75index to the first address in it. This will be 76incremented when you add data and decremented when you 77remove data. 78 79Let's add some stuff using `buffer:add`: 80 81``` 82#100 buffer:add 83#200 buffer:add 84#300 buffer:add 85``` 86 87And then retrieve the values: 88 89``` 90buffer:get n:put nl 91buffer:get n:put nl 92buffer:get n:put nl 93``` 94 95You can remove all values using `buffer:empty`: 96 97``` 98#100 buffer:add 99#200 buffer:add 100#300 buffer:add 101buffer:empty 102``` 103 104And ask the buffer how many items it contains: 105 106``` 107buffer:size n:put nl 108#100 buffer:add 109#200 buffer:add 110#300 buffer:add 111buffer:size n:put nl 112buffer:empty 113``` 114 115The other functions are `buffer:start`, which returns 116the address of the buffer, `buffer:end`, which returns 117the address of the last value, and `buffer:preserve`. 118The first is easy to demo: 119 120``` 121buffer:start Test eq? n:put nl 122``` 123 124The last one is useful. Only one buffer is ever active 125at a given time. The `buffer:preserve` combinator lets 126you execute a word, saving and restoring the current 127buffer indexes. So the word could assign and use a new 128buffer and this will reset the previous one after 129control returns. 130 131There are a few notes that need to be considered. The 132preserve combinator saves the start and current index 133but *not* the contents. If the word you call uses the 134same buffer, the contents will remain altered. 135 136Finally, the buffer words have one interesting trait: 137they store an ASCII NULL after adding each item to the 138buffer. This lets one use them to build strings easily. 139 140``` 141Test buffer:set 142$h buffer:add 143$e buffer:add 144$l buffer:add 145$l buffer:add 146$o buffer:add 147$, buffer:add 148#32 buffer:add 149$w buffer:add 150$o buffer:add 151$r buffer:add 152$l buffer:add 153$d buffer:add 154buffer:start s:put nl 155``` 156