Performs a circular shift of n elements on the operand stack by j positions.
1. Description
The roll operator performs a circular rotation of the top n elements on the operand stack. The rotation amount j can be positive (upward rotation) or negative (downward rotation).
Positive j values move elements toward the top of the stack, while negative j values move elements toward the bottom. The operation is circular, so elements that move off one end reappear at the other end.
This is a Level 1 operator, available in all PostScript implementations.
2. Syntax
anyn-1 ... any0 n j roll any(j-1) mod n ... any0 anyn-1 ... anyj mod n
2.1. Stack Effect
| Position | Content |
|---|---|
Top |
|
Top-1 |
|
Top-2 |
|
… |
… |
Top-(n+1) |
|
| Position | Content |
|---|---|
Top to Top-(n-1) |
Elements rotated by j positions (circular) |
3. Parameters
n-
Non-negative integer specifying how many elements to rotate. Must be ≥ 0.
j-
Integer specifying the rotation amount. Positive values rotate upward (toward top), negative values rotate downward.
anyn-1 … any0-
The n elements to be rotated.
5. Examples
5.1. Basic Usage
% Rotate 3 elements up by 1 position
(a)(b)(c) 3 1 roll % Stack: (c)(a)(b)
% Rotate 3 elements down by 1 position
(a)(b)(c) 3 -1 roll % Stack: (b)(c)(a)
% No rotation
(a)(b)(c) 3 0 roll % Stack: (a)(b)(c)
5.2. Multiple Rotations
% Rotate by 2 positions
(a)(b)(c)(d) 4 2 roll % Stack: (c)(d)(a)(b)
% Rotate by -2 positions
(a)(b)(c)(d) 4 -2 roll % Stack: (c)(d)(a)(b)
% Same result! (4-2 = 2 mod 4)
6. Advanced Examples
6.1. Implementing Stack Rotation Helpers
% Rotate top 3 elements: a b c -> b c a
/rot { % a b c -> b c a
3 1 roll
} def
% Reverse rotate: a b c -> c a b
/unrot { % a b c -> c a b
3 -1 roll
} def
1 2 3 rot % Stack: 2 3 1
1 2 3 unrot % Stack: 3 1 2
6.2. Moving Elements to Specific Positions
% Move element at position i to top
/bringToTop { % ... elem_i ... i n -> elem_i ...
% i is position from top (0-based)
% n is total number of elements
exch 1 add % n (i+1)
neg % n -(i+1)
roll
} def
10 20 30 40 50
2 5 bringToTop % Brings element at position 2 to top
% Stack: 30 10 20 40 50
7. Edge Cases and Common Pitfalls
Using roll requires at least n+2 elements on the stack (n elements plus n and j). Insufficient elements cause stackunderflow.
|
7.1. Stack Underflow
% BAD: Not enough elements
1 2 3
5 1 roll % ERROR: stackunderflow
% Need 5 elements, only have 3
9. PostScript Level
Available in: PostScript Level 1 and higher
This is a fundamental operator available in all PostScript implementations.
10. Error Conditions
stackunderflow-
The stack contains fewer than n+2 elements (n elements plus n and j).
1 2 3 5 1 roll % ERROR: stackunderflow rangecheck-
The value of n is negative.
1 2 3 -1 1 roll % ERROR: rangecheck typecheck-
Either n or j is not an integer.
1 2 3 3.5 1 roll % ERROR: typecheck 1 2 3 3 (not a number) roll % ERROR: typecheck
11. Performance Considerations
The roll operator has O(n) time complexity. For small values of n (like 2 or 3), it’s very fast. For larger values, consider whether you really need to rotate all those elements or if there’s a more efficient approach.
Frequently rotating large numbers of elements may indicate poor stack management strategy.
12. Best Practices
-
Use exch for two elements:
2 1 rolland2 -1 rollboth work, butexchis clearer -
Document rotations: Always comment what
rollis doing, as it’s not immediately obvious -
Consider index instead: Sometimes
psindexis clearer thanrollfor accessing buried elements -
Keep n small: Large rotations suggest stack management issues
-
Use standard patterns: Establish conventions like
3 1 rollfor rotating three elements
12.1. Common Rotation Patterns
% Three-element rotations (very common)
% a b c -> b c a
3 1 roll
% a b c -> c a b
3 -1 roll
% Four-element rotation to access buried value
% a b c d -> (use b)
3 -1 roll % b a c d
% Use b
% Restore: 3 1 roll
12.2. Clear Documentation Example
% Good: Document what roll accomplishes
/computeDistance { % x1 y1 x2 y2 -> distance
% Stack: x1 y1 x2 y2
3 -1 roll % x1 x2 y2 y1 - bring y1 to top
sub % x1 x2 dy
dup mul % x1 x2 dy^2
3 1 roll % dy^2 x1 x2 - bring x's to top
sub % dy^2 dx
dup mul % dy^2 dx^2
add sqrt % distance
} def
13. See Also
-
Operators Overview - Understanding PostScript operators
-
Stack Operations Guide - Stack manipulation tutorial
-
Stack Manipulation - All stack operators