Push a grammar token onto the stack
The push command is essential for managing the ℙ𝕖𝕡 and ℕ𝕠𝕞 parse-stack (which is a lifo stack of string items). The push command also increments the tape pointer. This means that after a push, the tape will be pointing to the next tape cell.
However, if the workspace buffer is empty at the time the push command is executed, then the pep machine is unchanged: the tape-pointer is not incremented. This behaviour is important for maintaining the tape and stack synchronised. The stack is designed to contain the language (or pattern) grammar parse-tokens and the tape is designed to contain the “attributes” which correspond to each of those tokens.
It is very common for a push command to be followed by a
.reparse
command. This is to ensure that all grammar rule
reductions take place.
# fragment
pop;pop;pop;
"direction*angle*newline*" {
clear; get; ++; get; --; put;
clear; add "action*"; push; .reparse
}
push;push;push;
The ℕ𝕠𝕞 fragment above corresponds to an XBNF rule
action := direction angle newline ;
The fragment doesn't really 'compile'; it just concatenates the 2 attributes in direction* and angle* and puts them into the new action* parse-token (although sometimes this is all that is required).
The behaviour of push is that it reads the workspace buffer
from the beginning until the 1st occurrence of the parse-token
delimiter . The default delimiter is '*' but this can be changed
with the delim
command (usually in a begin block).
The parse token delimiter is a single character which separates the parse-tokens when they are in the workspace buffer and it can be set to any character (even a space or dot).
The script below is a fairly non-standard use of push but illustrates some capabilities of the ℙ𝕖𝕡 machine. This prints one word per line and prints words with a '.' character on 2 lines.
read;
![:space:] {
whilenot [:space:];
# split a word on the first '.' using push
delim '.'; push;
!"" {
--; put; ++; clear; delim '*'; pop; add "\n"; get; add "\n";
print; clear; .restart
}
# change delim back before pop
delim '*'; pop; add "\n"; print; clear;
}
[:space:] { while [:space:]; clear; }
!"" { clear; add "cryptic error message!\n"; print; quit; }
ℙ𝕖𝕡 is a (string-based) virtual-machine and you can use it anyway that you would like.
If the workspace starts with the delimiter, then only the delimiter character will be pushed on the stack. This is not very useful because it is an empty token.
read; clear; add "*a"; push; state; clear;