Counts the number of elements on the operand stack and pushes this count onto the stack.
1. Description
The count operator returns the current depth of the operand stack as an integer. This is useful for stack management, debugging, and implementing stack-aware operations.
After execution, the stack contains one more element than before (the count itself), so the count value reflects the stack depth before count was executed.
This is a Level 1 operator, available in all PostScript implementations.
4. Return Values
Returns a non-negative integer representing the number of elements that were on the stack before count was executed.
5. Examples
5.1. Basic Usage
% Empty stack
clear count % Stack: 0
% Stack with elements
clear 1 2 3 count % Stack: 1 2 3 3
% After count, stack has one more element
clear 1 2 count % Stack: 1 2 2
count % Stack: 1 2 2 3
5.2. Checking Stack Depth
% Verify sufficient elements before operation
count 3 ge {
% At least 3 elements, safe to proceed
3 array astore pop
} {
(Insufficient elements on stack) print
} ifelse
6. Advanced Examples
6.1. Implementing cleartomark Safely
% Count elements before finding mark
/safeCountToMark {
count mark exch
% Find mark position
0 1 2 index 1 sub {
index type /marktype eq {
exch pop exit
} {
pop
} ifelse
} for
} def
6.2. Stack Depth Assertions
% Assert exact stack depth
/assertDepth { % ... expected -> ... (or error)
count 1 sub % Get actual depth (excluding expected)
1 index ne {
(Stack depth mismatch!) print
count =
} {
pop
} ifelse
} def
% Usage
clear 1 2 3
3 assertDepth % OK
4 assertDepth % Prints error
7. Edge Cases and Common Pitfalls
Remember that count itself adds one element to the stack, so count after count increases by 1 each time.
|
7.1. Count Adds to Stack
% CAUTION: count modifies the stack
clear
count % Stack: 0
count % Stack: 0 1 (not 0 0!)
count % Stack: 0 1 2
7.2. Using Count in Conditionals
% GOOD: Use count result immediately
count 0 eq {
(Stack is empty) print
} if
% BAD: Don't save count then test
count /depth exch def
depth 0 eq { % depth value is stale if stack changed!
(May not be empty) print
} if
7.3. Count Includes All Elements
% Count includes marks and all other elements
clear
mark 1 2 3
count % Stack: mark 1 2 3 4
% All 4 elements counted (including mark)
Use count immediately before the operation that needs to know stack depth. Don’t store the count value for later use, as the stack may change.
|
8. Related Commands
-
counttomark- Count elements until a mark -
clear- Remove all elements from stack -
pop- Remove single element -
copy- Copy n elements -
roll- Rotate n elements
9. PostScript Level
Available in: PostScript Level 1 and higher
This is a fundamental operator available in all PostScript implementations.
10. Error Conditions
stackoverflow-
The stack is at maximum capacity and cannot accommodate the count value. This is extremely rare in practice.
% (Only possible if stack nearly full)
11. Performance Considerations
The count operator is extremely fast with O(1) constant time complexity. The interpreter maintains a running count of stack elements, so this operation doesn’t need to traverse the stack.
Use count freely for debugging and stack management without performance concerns.
12. Best Practices
-
Use for safety checks: Always verify stack depth before operations that require specific numbers of elements
-
Immediate use: Use the count value immediately; don’t store it for later
-
Debugging aid: Excellent for understanding stack behavior during development
-
Combine with copy: Use
countto determine how many elements to copy -
Document assumptions: When procedures assume certain stack depths, document and verify with
count
12.1. Safe Procedure Patterns
% Check prerequisites before operation
/safeOperation { % a b c -> result
% Require exactly 3 arguments
count 3 lt {
(Error: safeOperation requires 3 arguments) print
quit
} if
% Perform operation knowing we have enough elements
add add
} def
% Usage
1 2 safeOperation % Prints error
1 2 3 safeOperation % Returns 6
12.2. Stack State Verification
% Verify procedure maintains stack balance
/testStackBalance { % proc -> (reports balance)
count % Save initial depth
exch exec % Execute procedure
count % Get final depth
exch sub % Calculate difference
dup 0 ne {
(Warning: stack imbalance: ) print =
} {
pop
(Stack balanced) print
} ifelse
} def
13. See Also
-
Operators Overview - Understanding PostScript operators
-
Stack Operations Guide - Stack manipulation tutorial
-
Debugging Guide - Using count for debugging
-
Stack Manipulation - All stack operators