by showmyiq » Sun Mar 17, 2013 11:41 am
Ok, now let’s see how we can modify the elements in the stack. The first operator we are going to discuss is the operator add. As the name states with this operator we can add two numbers. The syntax of the operator is: X Y add
X and Y are some random numeric values and the operator add states that we want to add them.
Now clear the stack with the clear command. Write down in the GS console the following commands:
1 2 add
stack
What is hiding behind this commands? Well, we first create in the stack the numeric elements 1 and 2, then we are adding them to each other (in this process it’s vital to notice that after we add them, they are destroyed from the stack) and push the value (3) on the top of the stack. If you execute the command you are going to receive this as results.
3
GS<1>
As you can see the stack has only 1 element and the value of this element is 3, the sum of the numbers 1 and 2. In this case X=1 and Y=2. Ok, what if we have a stack with just 2 numbers and we don’t supply X and Y to the add operator? Imagine you have this stack:
6
5
4
3
2
1
GS<6>
After we have created this stack, what is going to happen if we type the operator add?
Let’s test it!
11
4
3
2
1
GS<5>
As you can see the elements’ count dropped from 6 to 5. And the top element is 11 (the sum of 5 and 6). Why this happened? We didn’t supplied any arguments to the add operator?
Well, the thing is GS doesn’t care. The PostScript doesn’t pay attention to new rows (the enter button). It goes back and take the last two values you have used to construct your stack and use them as arguments to the add operator. The last elements we have constructed are 5 and 6, so the add operator use them as arguments.
Clear the stack now and put only 1 element in the stack. Type the add operator with no arguments. You should receive this:
Error: /stackunderflow in --add--
Operand stack:
1
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1932 1 3 %oparray_pop 1931 1 3 %oparray_pop 1915 1 3 %oparray_pop 1803 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval--
Dictionary stack:
--dict:1172/1684(ro)(G)-- --dict:0/20(G)-- --dict:77/200(L)--
Current allocation mode is local
GPL Ghostscript 9.07: Unrecoverable error, exit code 1
>Exit code: 1
That’s the usual error message you are going to receive, when you did something wrong. Don’t be afraid of it, just a regular PostScript complain. Why that happen? Because PostScript doesn’t care about arguments when it comes to operator add – but the stack should have at least 2 elements. We can define that add is destroying the top 2 elements of the stack and pushing their sum back, if add was used without arguments – X and Y.
The other operators in this chapter are with the same flexibility.
Operator sub – X Y sub (substitute the values, the result is X-Y)
Operator div – X Y div (divide the values, the result is X/Y)
Operator idiv – X Y idiv (again divide the values, but this time instead of X/Y, which can be rational value, it get rid of all the digits after the dot – we are going to test it later on this chapter. Very Important – X and Y should be integer values only!)
Operator mod – X Y mod (a famous reminder function, X is divided by Y and the remainder is the result. Very Important – X and Y should be integer values only!)
Operator mul – X Y mul (multiplication, the result is X*Y)
Operator neg – X neg (finding the negative value of a number, if you put X, you are going to receive –X)
Ok, now you should practice using all the operators in this chapter, because these are fundamentals operators and you need to understand them perfectly in order to proceed with the next chapters.
Let’s write some examples and inspect the results. What if we clear the stack and enter this command: 25.5 8 idiv
Yes, error. As we stated the arguments supplied to idiv operator and mod operator should be always integer values. That’s why the command: 25.5 8 mod, will again give us an error. Pay attention to that, because in the following command, an error will appear:
clear
1 2 3 4 5 6 7 8 9 10
add
sub
div
idiv
mod
mul
neg
A good puzzle to solve, will be the task to find all the possible rearrangements of the operators in this example, so the command to be completed successfully. Feel free to add your answer in this chapter as reply. A one good rearrangement is as follows:
clear
1 2 3 4 5 6 7 8 9 10
mod
idiv
add
sub
div
mul
neg
All this operators in this good rearrangement will successfully completed their tasks and the final stack will look like this:
20.0
3
2
1
GS<4>
I want to show you step by step the modifications in the stack. If you want to follow manually the modifications, you can modify the source code with adding stack command after each operator used:
clear
1 2 3 4 5 6 7 8 9 10
stack
mod
stack
idiv
stack
add
stack
sub
stack
div
stack
mul
stack
neg
stack
Ok, here is the deal. First stack command will show us this:
10
9
8
7
6
5
4
3
2
1
This is our starting stack and the first operator is ready to start – the mod operator. What it’s going to do? Well in this case the PostScript is going to calculate the command: 9 10 mod. In this case we are going to divide two integer values, destroy them from the stack and push back the reminder. As you can see 9 and 10 are integer, so no nasty errors here. 9 divided by 10 is 0 with reminder 9. That’s explain the next stack command’ results:
9
8
7
6
5
4
3
2
1
Now we are ready to execute the operator idiv. In fact the command will look like this: 8 9 idiv
As you can see 8 is less than 9, so the result will be 0. If I need to be more detailed, the result is 0.8888888888888889, but since idiv doesn’t care the digits after the decimal point, the result will be 0.That’s explain the next stack print:
0
7
6
5
4
3
2
1
Now we are entering the domain of the add operator. 0 7 add , which is equal to 7.
7
6
5
4
3
2
1
So far, so good. Now we are situated in the operator sub. The command will look like this: 6 7 sub. Do the math and we have 6-7=-1, so the result will be -1.
-1
5
4
3
2
1
Now we are going to the next operator – div. The command will look like this: 5 -1 div. If we do the math, we have 5/(-1) equals to -5
-5.0
4
3
2
1
Then we have the mul. 4 -5.0 mul, which is equals to -20.
-20.0
3
2
1
And the final operator here is neg. So the command will be -20.0 neg, which is equal to 20, so the final result/stack is:
20.0
3
2
1
You can enjoy and practice with different starting elements of the stack, or rearranging the current one, or rearranging the operators… Just play with the operators and feel them. There are other operators too, but we are going to discuss them in future chapters.