Some interpreters, such as Reginald, allow a Data stack to be divided up into "buffers". You mark the start of a buffer by making a call to the MAKEBUF() built-in function. Then, any lines that you subsequently PUSH or QUEUE get placed into that buffer.

For example, here we create a buffer in the current Data stack, and then PUSH two items into it:

/* Mark the start of a buffer */
remaining = MAKEBUF()

/* Push two items into this buffer */
PUSH 'item 1'
PUSH 'item 2'
You can create as many buffers as you desire. But just like with items in the stack, you can't access buffers you created earlier until you retrieve/remove all the items in buffers you created later.

The big advantage to using buffers is that you can quickly delete all of the items placed into a buffer (as well as the buffer marker) with a single call to DROPBUF().

Here we delete the last buffer we created, and all the items in it:

/* Delete the last buffer */
remaining = DROPBUF(1)
When you PULL or PARSE PULL all of the items from a buffer, then the buffer mark is also deleted.

DESBUF() deletes all items in the current stack, including all of the buffer markers.

There is always an implicit buffer marker at the very start (ie, top) of a stack, so you never need to put a buffer marker in an empty stack.