7.5.1 Implementation of the stack in Regina 0.05h
In Regina, the stack is implemented as an integral, private part
of the interpreter. The advantage of this is that stack operations
are very fast. On the other hand, it means that two interpreters
running on the same machine does not use the same stack. Further,
it means that a program can not on its own initiative communicate
with the stack; such piping must be set up by the interpreter at
the invocation time of the program.

Whenever the REXX programmer wants to execute a command and let
that command either flush the output to the stack, or read its
input from the stack, this has to be arranged by the interpreter
itself.  In Regina this is normally done by prepending or
appending certain terms to the command to be executed.

Consider the following command clauses for Regina:

     ‘ls >LIFO’
     ‘who >FIFO’
     ‘LIFO> wc’
     ‘ps’
     ‘LIFO> sort >FIFO’

For all these commands, the “piping” terms are stripped off the
command string before the command is sent to the command
interpreter of the operating system. Thus, the command interpreter
only sees the commands ls, who, wc, and sort. The terms stripped
off, are used as indicators of how the input and output is to be
coupled with the stack. Note that it is important not to confuse
the redirection of output to the stack and input from the stack in
Regina with the redirection of the Unix shells. The two can be
mixed in command lines, but are still two different concepts.

The first command will execute the ls command, and redirect the
output from it to the stack in a LIFO fashion. The second executes
the command who and redirects the output to the stack to, but in a
FIFO fashion. The third command executes the wc, but lets the
standard input of that command come from the stack.  Actually, it
is irrelevant whether FIFO> or LIFO> is used for input; the
strings are read from the top of the stack in both cases.  The
fourth command is a plain ps command without any redirection to or
from the stack. The last command executes the sort program and
lets it read its input from the stack, and redirect the output to
the stack.

Regina allows a command to take both an input and an output
“redirection” to a stack, as showed in the last example above.
However, it also guarantees that the output is not available in
the stack before the command has terminated. The output from the
command is stored in a temporary stack, and flushed to the
ordinary stack after the command is terminated. Thus, the command
will not start to read its own output.

Note that this temporary buffering of command output is the
default behavior, which might be set up to something different at
your site.

In addition, you can change it through the OPTIONS instruction, by
using either FLUSHSTACK or BUFFERSTACK as “parameters”.

Furthermore, Regina supports the standard TRL REXX stack interface
functionality, like PARSE PULL, PULL, QUEUE, PUSH, the QUEUED()
built-in function, and the SAA API stack interface. In addition,
there are a few extra built-in functions, which are supposed to
provide compatibility with other REXX implementations. These are:

Again, note the difference between Regina’s redirection and Unix
redirection. In Regina, only the terms LIFO> and FIFO> (when first
in the command string), and the terms >LIFO and >FIFO (when last
in the command string), will be interpreted as redirection
directives. These terms will be stripped off the command string.
All other redirection directives will be left untouched. If you
should happen to need to redirect output from a Unix command to
the file FIFO or LIFO, then you can append a space at the end.
That will make Regina ignore the redirection term and the space is
ignored by Unix.

Note that this particular form of redirection of command input and
output will most probably disappear in future versions of Regina,
where it will probably be replaced by an extended ADDRESS
instruction.


BUFTYPE()

This function is used for displaying the contents of the stack. It
will display both the string and notify where the buffers are
displayed. It is meant for debugging, especially interactive, when
you need to obtain information about the contents of the stack. It
always returns the nullstring, and takes no parameters.

Here is an example of the output from calling BUFTYPE (note that
the second and fourth buffers are empty):

     ==> Lines: 4
     ==> Buffer: 3
     “fourth line pushed, in third buffer”
     ==> Buffer: 2
     ==> Buffer: 1
     “third line pushed, in first buffer”
     ==> Buffer: 0
     “second line pushed, in ‘zeroth’ buffer”
     “first line pushed, in ‘zeroth’ buffer”
     ==> End of Stack


BUFTYPE()


DESBUF()

This function removes all buffers on the stack, it is really just
a way of clearing the whole stack for buffers as well as strings.
Functionally, it is equivalent to executing DROPBUF with a
parameter of 0.  (Actually, this is a lie, since DROPBUF is not
able to take zero as a parameter.  Rather, it is equivalent to
executing DROPBUF with 1 as parameter and then executing DROPBUF
without a parameter, but this is a subtle point.) It will return
the number of buffers left on the stack after the function has
been executed. This should be 0 in all cases.

     DESBUF()


DROPBUF([number])

This function will remove zero or more buffers from the stack.
Called without a parameter, it will remove the topmost buffer from
the stack, provided that there were at least one buffer in the
stack. If there were no buffers in the stack, it will remove all
strings in the stack, i.e. remove the zeroth buffer.

If the parameter number was specified, and the stack contains a
buffer with an assigned number equal to number, then that buffer
itself, and all strings and buffers above it on the stack will be
removed; but no strings or buffers below the numbered buffer will
be touched. If number refers to a buffer that does not exist in
the stack; no strings or buffers in the stack is touched.

As an extra extension, in Regina the DROPBUF() built-in function
can be given a non-positive integer as parameter. If the name is
negative then it will convert that number to its absolute value,
and remove that many buffers, counted from the top. This is
functionally equivalent to repeating DROPBUF() without parameters
for so many times as the absolute value of the negative number
specifies. Note that using -0 as parameter is equivalent to
removing all strings and buffers in the stack, since -0 is
equivalent to normal 0. The number is converted during evaluation
of parameters prior to the call to the DROPBUF() routine, so the
sing is lost.

The value returned from this function is the number of buffers
left on the stack after the buffers to be deleted have been
removed.  Obviously, this will be a non-negative integer. This
too, deviates from the behavior of the DROPBUF command under CMS,
where zero is always returned.

DROPBUF(  2 remove buffer 3 and 4
3)
DROPBUF(  0 no buffers on the stack
4)
DROPBUF(  4 if there where 5 buffers
)


MAKEBUF()

Creates a new buffer on the stack, at the current top of the
stack.  Each new buffer will be assigned a number; the first
buffer being assigned the number 1. A new buffer will be assigned
a number which is one higher than the currently highest number of
any buffer on the stack. In practice, this means that the buffers
are numbered, with the bottom-most having the number 1 and the
topmost having a number which value is identical to the number of
buffers currently in the stack.

The value returned from this function is the number assigned to
the newly created buffer. The assigned number will be one more
than the number of buffers already in the stack, so the numbers
will be “recycled”. Thus, the assigned numbers will not
necessarily be in sequence.

MAKEBUF(  1 if no buffers existed
)
MAKEBUF(  6 if 5 buffers existed
)

                                 
                                 

PREV NEXT