# 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. – cjorssen Feb 1 '12 at 18:11
• yes but how to translate these guards ? How to define this function with a natural algorithm ? – Alain Matthes Feb 1 '12 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 pops) <any> and replaces it (or pushes) 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 pops) <num> and pushes -<num>;
• asin: arcsin function. So, <num> asin takes (or pops) <num> and pushes 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 pops) <num1> <num2> and pushes 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 pops) <num1> <num2> and pushes 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 ? – Alain Matthes Feb 1 '12 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 '12 at 19:35
• condition { true part }{ false part } ifelse – user2478 Feb 1 '12 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