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