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