# From postscript through pgfmath

I don't understand the next syntax also I would like (if possible) a traduction of the next function with `pgfmath`

`````` /fct {dup 1 gt {pop 90}{dup 1 neg lt {pop 90 neg}{asin} ifelse} ifelse} def
``````
• This is the asin function with some guards regarding the definition. Feb 1, 2012 at 18:11
• yes but how to translate these guards ? How to define this function with a natural algorithm ? Feb 1, 2012 at 18:18

Here is an explanation of how to interpret the postscript code. It is probably not an answer, but at least a guide to understanding it. Remember that postscript uses RPN, so understanding it requires a bit of backwards reading.

According to the Postscript Language Reference Manual, the following definitions are used when executing `ifelse` (by example):

``````a b gt {a} {b} ifelse
``````
1. The interpreter encounters the executable names `a` and `b` in turn and looks them up. Assume both names are associated with numbers. Executing the numbers causes them to be pushed on the operand stack.
2. The `gt` (greater than) operator removes two operands from the stack and compares them. If the first operand is greater than the second, it pushes the boolean value `true`. Otherwise, it pushes `false`.
3. The interpreter now encounters the procedure objects `{a}` and `{b}`, which it pushes on the operand stack.
4. The `ifelse` operator takes three operands: a boolean object and two procedures. If the boolean object’s value is `true`, `ifelse` causes the first procedure to be executed; otherwise, it causes the second procedure to be executed. All three operands are removed from the operand stack before the selected procedure is executed.

Other commands used are:

• `dup`: duplicates the current object on the stack. So, `<any> dup` takes (or `pop`s) `<any>` and replaces it (or `push`es) with `<any> <any>`;
• `pop`: removes the top element from the stack. So, `<any> pop` removes `<any>`;
• `neg`: an arithmetic operators that takes one argument on the top of the stack and negates it. So `<num> neg` takes (or `pop`s) `<num>` and `push`es `-<num>`;
• `asin`: arcsin function. So, `<num> asin` takes (or `pop`s) `<num>` and `push`es the arcsin of `<num>`;
• `gt`: evaluates the top to stack elements in a "greater than" fashion and returns `true`/`false`. So, `<num1> <num2> gt` takes (or `pop`s) `<num1> <num2>` and `push`es `true` if `<num1>`>`<num2>`, or `false` otherwise;
• `lt`: evaluates the top to stack elements in a "less than" fashion and returns `true`/`false`. So, `<num1> <num2> lt` takes (or `pop`s) `<num1> <num2>` and `push`es `true` if `<num1>`<`<num2>`, or `false` otherwise;
• `def`: store the value on the top of the stack in a variable. So `/<var> <any> def` stores `<any>` in the variable `/<var>`.

Consequently, it is possible to rewrite the postscript code

``````/fct {dup 1 gt {pop 90}{dup 1 neg lt {pop 90 neg}{asin} ifelse} ifelse} def
``````

as (using pseudocode):

``````X = top-of-stack

if (X > 1) then
fct = 90
else
if (X < -1) then
fct = -90
else
fct = arcsin(X)
end if
end if
``````
• What is the role (part) of the braces ? Feb 1, 2012 at 19:28
• @Altermundus: Based on Herbert's answer, the outer braces store the entire definition in `/fct` (almost like an unexpanded command). The inner braces are required since `ifelse` could condition on a whole group of operators (like `pop 90 neg`). Without the inner braces a single operator would be used as the `true`/`false` clause.
– Werner
Feb 1, 2012 at 19:35
• `condition { true part }{ false part } ifelse`
– user2478
Feb 1, 2012 at 20:21

`/fct {dup 1 gt {pop 90}{dup 1 neg lt {pop 90 neg}{asin} ifelse} ifelse} def`

is the same as:

``````sub fct(arg){    # arg in degrees
if (arg > 1)  return 90
if (arg < -1) return -90
return asin(arg)
}

sub asin(arg){   # arg in degrees