CHAPTER 18. PREPROCESSOR MANUAL 362
18.2.5
Phony variables
There are six phony variables >#>, <#<, >>>, $#$, _#_ and |#|.
>#> works very much like @1@, @2@, etc. in that it parses a string. But instead of assigning it to a register, it is put on the string stack directly. <#< drops the top of the stack, so the sequence >#>
<#< simply ignores a string:
:macro create @1@ @2@ >#> <#< >#> <#< #2# string #1# ; create mystring 20 chars allot
>>> takes the next name or back quoted string and puts it on the string stack. So this will assign ”Hello world!” to the first register:
:macro hello >>> ‘ Hello world¡ <1< ;
$#$ is much like the $1$ through $4$ commands, except it puts the parsed string on the string stack. Just like its cousins, it requires a delimiter. We could rewrite our implementation of ”S\"” as follows: include lib/escape.4th
:macro S\" $#$ " ‘ S" ‘ |#| >>> " |#| s>escape ;
S\" \tAnd the winner is:\t\q4tH compiler\q!"
Then _#_, which simply prints the top of the stack. Finally |#|, which is used to concatenate strings. Normally before a string is printed a space or newline is added. |#| takes the top of the string stack and prints it as is. This way you can build macros like this, which prints a string constant:
:macro literal: @1@ ‘ S" ‘ >1> |#| >>> " |#| ; literal: Hello
Needless to say that phony variables are only recognized within macros.
18.2.6
Branching and looping
The preprocessor also offers some simple branching and looping functionality. It may seem unusual and awkward at first, but it does the job. Basically, it exits the macro without discarding the flag when the comparison renders false, e.g.:
:macro ex1 >>> 0 @if ‘ This is never printed‘ ;
:macro example ‘ Print this‘ ex1 @drop ; example
Will only print ”Print this”. @if will render true when the numerical equivalent of the string on the stack is non-zero. However, the flag - either zero or non-zero - will remain on the stack, so we have to drop it one nesting level lower by calling @drop, which is a synonym for <#<. We can also add an ”else” clause easily:
:macro ex1 >>> 0 @if ‘ This is never printed‘ ;
:macro ex2 ex1 @else ‘ But this is‘ ;
:macro example ‘ Print this‘ ex2 @drop ; example