User Tools

Site Tools


prpl:prpl_notation_styles

This is an old revision of the document!


PRPL is typically referred to as a “Reverse Polish Notation” language (hence the “RPL” in it's name. It is an extension of CRPL used in CW3, with additional facilities beyond that.

There are 3 distinct ways to write PRPL code.

  • Stack Notation (traditional)
  • Warp Notation (developed for CW3)
  • Accessor Notation (new for PRPL)

Stack Notation

Every PRPL operand takes zero or more arguments from a “stack”, pushes zero or more operands onto the “stack, or does both. In order to diagram the number of arguments consumed or produced, the following notation is included in every description following:

  • The term is defined by two dashes: --
  • Preceding the term are the arguments consumed from the stack.
  • Following the term are the arguments pushed onto the stack.

For instance, the instruction to add two numbers are:

4 5 add

Stack notation to represent this will be:

 4 5 -- 9

In general, if we do not know the exact values of the arguments, an indicator of the argument would be given. Thus if we know the add command takes two input arguments and produces one output argument, then we notate it like this

 n1 n2 -- n3 

Note: Unless explicitly noted otherwise, all instructions are destructive stack operations in that they will remove as many arguments as is required for their execution from the stack and replace those with the output from their execution. In the example above, the original two items on the stack have been replaced by their sum.

Likewise, note that the most recent item pushed on to the stack will also be the first item to be removed. This is referred to as LIFO (Last In, First Out) processing.

The following convention is followed to represent items on the stack notation

b Boolean ; nominally a 1 or a zero, representing True or False
i Integer ; an integer. The PRPL run-time will, if possible, convert the argumant to an integer.
n Term ; a generic argument. Any term that will be accepted by the instruction. If possible, the PRPL run-time will attempt conversion between types.
f Float ; a floating point value. If possible, the PRPL run-time will attempt conversion between types.
x, y Coordinate ; an integer that represents a valid X- or Y-coordinate on the map.
L List ; a list is capable of storing multiple values in an orderly system.
s String ; a string of one or more text characters. If possible, numeric values will be converted at run-time.

Warp Notation

An extra and optional operator to PRPL allows for a reversed order that you write some things in PRPL. It doesn't change a thing about the stack, or how PRPL works. It only gives you a syntax alternative that can make things easier to read in some cases.

This operator is the “warp” operator since it warps things around. In more technical terms, it allows for prefix notation. Take the following example:

3 4 add 

This means to push 3 to the stack, push 4 to the stack, then to call “add”. Add pops two items from the stack, adds them together, then pushes the result back. So stack notation for “add” is:

n1 n2 -- n3

This means two items on the stack before the operation, and one item on the stack afterwards. This is all PRPL (or RPL, or forth…) standard stuff and the primary principle of the language. This remains unchanged and untouched.

Take a second example:

CurrentCoords GetCreeper 1 gt if
   "Creeper Greater than 1" Trace
endif

This looks at the current coordinates, gets the creeper there, checks if it is greater than 1. If so, trace the string “Creeper Greater than 1” to the trace log. Because of the way the stack works, you have to push two coordinates to the stack first (CurrentCoords does that), then call GetCreeper. That takes two items from the stack, uses them as coordinates, then pushes the value of the creeper at that map location back to the stack. The number 1 is then pushed to the stack, and the “gt” call takes two items from the stack and does a “greater than” comparison between them. The result is either 0 (false) or 1 (true) and that is pushed back to the stack. Finally, the “if” statement pops the result of the “gt” call from the stack and then either allows execution to pass to the next statement, or jumps to the “endif”.

Again, PRPL 101.

Now, introducing the Warp operator.

3 4 add

can become

add (3 4)

The open parenthesis ”(“ means to warp the previous command to the closing parenthesis ”)“ during compilation. There is no run time penalty for doing this since it is just a syntax trick. The compiler literally 'warps' “add” from before the 3 to after the 4 when this example is compiled.

This also means the same thing:

3 add(4)

Here, the “add” warps from before the 4 to after the 4, resulting in “3 4 add” which is the exact same thing as the first example.

Take the second example. It now can become:

if ( GetCreeper(CurrentCoords)  gt (1) )
   Trace ("Creeper Greater than 1")
endif

Notice that spaces before or after a warp operator ( which are parentheses) don't matter. You can put spaces, or you can bump the warp operator up right next to something else.

Note also that this syntax is totally optional and can be intermixed with standard RPL notation as seems appropriate. For instance, assignments still look better without warping.

7 ->x

This means to assign 7 to the variable “x”. Or “seven goes into x”. So does this:

->x(7)

Like any language, you can write some really obfuscated code if you try (http://www.ioccc.org/years.html).

For instance take this clean piece of code:

CurrentCoords GetCreeper 1 gt if
   CurrentCoords -10 SetCreeper
endif

Here it is in bizarro form:

endif(SetCreeper(-10(CurrentCoords(if(gt(1(GetCreeper(CurrentCoords))))))))

Here's the same code with just one oddball warp:

endif ( if (GetCreeper(CurrentCoords) gt (1))
      SetCreeper(CurrentCoords -10)
)

Accessor Notation

prpl/prpl_notation_styles.1476710517.txt.gz · Last modified: 2025/02/14 14:56 (external edit)