postsvg 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +19 -0
- data/.rubocop_todo.yml +141 -0
- data/Gemfile +15 -0
- data/LICENSE +25 -0
- data/README.adoc +473 -0
- data/Rakefile +10 -0
- data/docs/POSTSCRIPT.adoc +13 -0
- data/docs/postscript/fundamentals.adoc +356 -0
- data/docs/postscript/graphics-model.adoc +406 -0
- data/docs/postscript/implementation-notes.adoc +314 -0
- data/docs/postscript/index.adoc +153 -0
- data/docs/postscript/operators/arithmetic.adoc +461 -0
- data/docs/postscript/operators/control-flow.adoc +230 -0
- data/docs/postscript/operators/dictionary.adoc +191 -0
- data/docs/postscript/operators/graphics-state.adoc +528 -0
- data/docs/postscript/operators/index.adoc +288 -0
- data/docs/postscript/operators/painting.adoc +475 -0
- data/docs/postscript/operators/path-construction.adoc +553 -0
- data/docs/postscript/operators/stack-manipulation.adoc +374 -0
- data/docs/postscript/operators/transformations.adoc +479 -0
- data/docs/postscript/svg-mapping.adoc +369 -0
- data/exe/postsvg +6 -0
- data/lib/postsvg/cli.rb +103 -0
- data/lib/postsvg/colors.rb +33 -0
- data/lib/postsvg/converter.rb +214 -0
- data/lib/postsvg/errors.rb +11 -0
- data/lib/postsvg/graphics_state.rb +158 -0
- data/lib/postsvg/interpreter.rb +891 -0
- data/lib/postsvg/matrix.rb +106 -0
- data/lib/postsvg/parser/postscript_parser.rb +87 -0
- data/lib/postsvg/parser/transform.rb +21 -0
- data/lib/postsvg/parser.rb +18 -0
- data/lib/postsvg/path_builder.rb +101 -0
- data/lib/postsvg/svg_generator.rb +78 -0
- data/lib/postsvg/tokenizer.rb +161 -0
- data/lib/postsvg/version.rb +5 -0
- data/lib/postsvg.rb +78 -0
- data/postsvg.gemspec +38 -0
- data/scripts/regenerate_fixtures.rb +28 -0
- metadata +118 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
= Stack Manipulation Operators
|
|
2
|
+
|
|
3
|
+
== General
|
|
4
|
+
|
|
5
|
+
Stack manipulation operators work with the operand stack, allowing you to
|
|
6
|
+
rearrange, duplicate, and remove stack elements. These are essential for
|
|
7
|
+
managing data flow in PostScript programs.
|
|
8
|
+
|
|
9
|
+
The operand stack is a Last-In-First-Out (LIFO) data structure that holds
|
|
10
|
+
operands for operators.
|
|
11
|
+
|
|
12
|
+
[[dup]]
|
|
13
|
+
== dup
|
|
14
|
+
|
|
15
|
+
=== General
|
|
16
|
+
|
|
17
|
+
The `dup` operator duplicates the top element of the stack.
|
|
18
|
+
|
|
19
|
+
=== Syntax
|
|
20
|
+
|
|
21
|
+
[source,postscript]
|
|
22
|
+
----
|
|
23
|
+
any dup <1> <2>
|
|
24
|
+
----
|
|
25
|
+
<1> Element to duplicate
|
|
26
|
+
<2> Operator that duplicates top element
|
|
27
|
+
|
|
28
|
+
Where,
|
|
29
|
+
|
|
30
|
+
`any`:: Any object on the stack
|
|
31
|
+
|
|
32
|
+
Stack effect: `any -- any any`
|
|
33
|
+
|
|
34
|
+
=== Examples
|
|
35
|
+
|
|
36
|
+
[example]
|
|
37
|
+
====
|
|
38
|
+
[source,postscript]
|
|
39
|
+
----
|
|
40
|
+
5 dup mul % Square a number: [5 5] → [25]
|
|
41
|
+
----
|
|
42
|
+
|
|
43
|
+
Duplicates 5, then multiplies: 5 × 5 = 25.
|
|
44
|
+
====
|
|
45
|
+
|
|
46
|
+
[example]
|
|
47
|
+
====
|
|
48
|
+
[source,postscript]
|
|
49
|
+
----
|
|
50
|
+
100 dup dup % [100 100 100]
|
|
51
|
+
3 1 roll % Rearrange if needed
|
|
52
|
+
add add % Sum all three: 300
|
|
53
|
+
----
|
|
54
|
+
|
|
55
|
+
`dup` can be used multiple times to create multiple copies.
|
|
56
|
+
====
|
|
57
|
+
|
|
58
|
+
[[pop]]
|
|
59
|
+
== pop
|
|
60
|
+
|
|
61
|
+
=== General
|
|
62
|
+
|
|
63
|
+
The `pop` operator removes and discards the top element from the stack.
|
|
64
|
+
|
|
65
|
+
=== Syntax
|
|
66
|
+
|
|
67
|
+
[source,postscript]
|
|
68
|
+
----
|
|
69
|
+
any pop <1> <2>
|
|
70
|
+
----
|
|
71
|
+
<1> Element to discard
|
|
72
|
+
<2> Operator that removes top element
|
|
73
|
+
|
|
74
|
+
Where,
|
|
75
|
+
|
|
76
|
+
`any`:: Any object to discard
|
|
77
|
+
|
|
78
|
+
Stack effect: `any -- `
|
|
79
|
+
|
|
80
|
+
=== Examples
|
|
81
|
+
|
|
82
|
+
[example]
|
|
83
|
+
====
|
|
84
|
+
[source,postscript]
|
|
85
|
+
----
|
|
86
|
+
5 10 15 pop % [5 10] - 15 discarded
|
|
87
|
+
add % [15]
|
|
88
|
+
----
|
|
89
|
+
|
|
90
|
+
Removes unwanted values from the stack.
|
|
91
|
+
====
|
|
92
|
+
|
|
93
|
+
[[exch]]
|
|
94
|
+
== exch
|
|
95
|
+
|
|
96
|
+
=== General
|
|
97
|
+
|
|
98
|
+
The `exch` operator exchanges the positions of the top two stack elements.
|
|
99
|
+
|
|
100
|
+
=== Syntax
|
|
101
|
+
|
|
102
|
+
[source,postscript]
|
|
103
|
+
----
|
|
104
|
+
any1 any2 exch <1> <2> <3>
|
|
105
|
+
----
|
|
106
|
+
<1> First element
|
|
107
|
+
<2> Second element
|
|
108
|
+
<3> Operator that exchanges them
|
|
109
|
+
|
|
110
|
+
Where,
|
|
111
|
+
|
|
112
|
+
`any1, any2`:: Any two objects on stack
|
|
113
|
+
|
|
114
|
+
Stack effect: `any1 any2 -- any2 any1`
|
|
115
|
+
|
|
116
|
+
=== Examples
|
|
117
|
+
|
|
118
|
+
[example]
|
|
119
|
+
====
|
|
120
|
+
[source,postscript]
|
|
121
|
+
----
|
|
122
|
+
10 5 exch div % [10 5] → [5 10] → [2]
|
|
123
|
+
----
|
|
124
|
+
|
|
125
|
+
Exchanges operands for division: 10 ÷ 5 = 2.
|
|
126
|
+
====
|
|
127
|
+
|
|
128
|
+
[example]
|
|
129
|
+
====
|
|
130
|
+
[source,postscript]
|
|
131
|
+
----
|
|
132
|
+
3 4 exch sub % 4 - 3 = 1
|
|
133
|
+
----
|
|
134
|
+
|
|
135
|
+
Reverses subtraction order.
|
|
136
|
+
====
|
|
137
|
+
|
|
138
|
+
[[roll]]
|
|
139
|
+
== roll
|
|
140
|
+
|
|
141
|
+
=== General
|
|
142
|
+
|
|
143
|
+
The `roll` operator rotates the top n elements of the stack by j positions.
|
|
144
|
+
Positive j rolls elements up (toward top), negative j rolls down.
|
|
145
|
+
|
|
146
|
+
=== Syntax
|
|
147
|
+
|
|
148
|
+
[source,postscript]
|
|
149
|
+
----
|
|
150
|
+
any1 ... anyn n j roll <1> <2> <3>
|
|
151
|
+
----
|
|
152
|
+
<1> Number of elements to roll
|
|
153
|
+
<2> Number of positions to roll
|
|
154
|
+
<3> Operator that performs roll
|
|
155
|
+
|
|
156
|
+
Where,
|
|
157
|
+
|
|
158
|
+
`n`:: Number of elements to roll (integer)
|
|
159
|
+
`j`:: Number of positions (integer, positive=up, negative=down)
|
|
160
|
+
|
|
161
|
+
Stack effect: `any1 ... anyn n j -- anyn any1 ... anyn-1` (for j=1)
|
|
162
|
+
|
|
163
|
+
=== Examples
|
|
164
|
+
|
|
165
|
+
[example]
|
|
166
|
+
====
|
|
167
|
+
[source,postscript]
|
|
168
|
+
----
|
|
169
|
+
1 2 3 3 1 roll % [2 3 1] - roll up once
|
|
170
|
+
----
|
|
171
|
+
|
|
172
|
+
Moves bottom element to top.
|
|
173
|
+
====
|
|
174
|
+
|
|
175
|
+
[example]
|
|
176
|
+
====
|
|
177
|
+
[source,postscript]
|
|
178
|
+
----
|
|
179
|
+
1 2 3 3 -1 roll % [3 1 2] - roll down once
|
|
180
|
+
----
|
|
181
|
+
|
|
182
|
+
Moves top element to bottom.
|
|
183
|
+
====
|
|
184
|
+
|
|
185
|
+
[[copy]]
|
|
186
|
+
== copy
|
|
187
|
+
|
|
188
|
+
=== General
|
|
189
|
+
|
|
190
|
+
The `copy` operator duplicates the top n elements of the stack.
|
|
191
|
+
|
|
192
|
+
=== Syntax
|
|
193
|
+
|
|
194
|
+
[source,postscript]
|
|
195
|
+
----
|
|
196
|
+
any1 ... anyn n copy <1> <2>
|
|
197
|
+
----
|
|
198
|
+
<1> Number of elements to copy
|
|
199
|
+
<2> Operator that copies elements
|
|
200
|
+
|
|
201
|
+
Where,
|
|
202
|
+
|
|
203
|
+
`n`:: Number of elements to duplicate (integer)
|
|
204
|
+
|
|
205
|
+
Stack effect: `any1 ... anyn n -- any1 ... anyn any1 ... anyn`
|
|
206
|
+
|
|
207
|
+
=== Examples
|
|
208
|
+
|
|
209
|
+
[example]
|
|
210
|
+
====
|
|
211
|
+
[source,postscript]
|
|
212
|
+
----
|
|
213
|
+
10 20 30 3 copy % [10 20 30 10 20 30]
|
|
214
|
+
----
|
|
215
|
+
|
|
216
|
+
Copies top 3 elements.
|
|
217
|
+
====
|
|
218
|
+
|
|
219
|
+
[[clear]]
|
|
220
|
+
== clear
|
|
221
|
+
|
|
222
|
+
=== General
|
|
223
|
+
|
|
224
|
+
The `clear` operator removes all elements from the operand stack.
|
|
225
|
+
|
|
226
|
+
=== Syntax
|
|
227
|
+
|
|
228
|
+
[source,postscript]
|
|
229
|
+
----
|
|
230
|
+
clear <1>
|
|
231
|
+
----
|
|
232
|
+
<1> Operator that clears stack
|
|
233
|
+
|
|
234
|
+
Where,
|
|
235
|
+
|
|
236
|
+
Stack effect: `any... -- ` (removes everything)
|
|
237
|
+
|
|
238
|
+
=== Examples
|
|
239
|
+
|
|
240
|
+
[example]
|
|
241
|
+
====
|
|
242
|
+
[source,postscript]
|
|
243
|
+
----
|
|
244
|
+
1 2 3 4 5 clear % [] - stack now empty
|
|
245
|
+
----
|
|
246
|
+
|
|
247
|
+
Useful for recovering from errors or resetting state.
|
|
248
|
+
====
|
|
249
|
+
|
|
250
|
+
[[count]]
|
|
251
|
+
== count
|
|
252
|
+
|
|
253
|
+
=== General
|
|
254
|
+
|
|
255
|
+
The `count` operator pushes the number of elements currently on the operand
|
|
256
|
+
stack.
|
|
257
|
+
|
|
258
|
+
=== Syntax
|
|
259
|
+
|
|
260
|
+
[source,postscript]
|
|
261
|
+
----
|
|
262
|
+
count <1>
|
|
263
|
+
----
|
|
264
|
+
<1> Operator that counts stack elements
|
|
265
|
+
|
|
266
|
+
Where,
|
|
267
|
+
|
|
268
|
+
Stack effect: `-- n` (n is number of elements)
|
|
269
|
+
|
|
270
|
+
=== Examples
|
|
271
|
+
|
|
272
|
+
[example]
|
|
273
|
+
====
|
|
274
|
+
[source,postscript]
|
|
275
|
+
----
|
|
276
|
+
1 2 3 count % [1 2 3 3] - 3 elements
|
|
277
|
+
----
|
|
278
|
+
|
|
279
|
+
Returns stack depth.
|
|
280
|
+
====
|
|
281
|
+
|
|
282
|
+
[[index]]
|
|
283
|
+
== index
|
|
284
|
+
|
|
285
|
+
=== General
|
|
286
|
+
|
|
287
|
+
The `index` operator duplicates the nth element from the top of the stack,
|
|
288
|
+
where 0 is the top element.
|
|
289
|
+
|
|
290
|
+
=== Syntax
|
|
291
|
+
|
|
292
|
+
[source,postscript]
|
|
293
|
+
----
|
|
294
|
+
anyn ... any0 n index <1> <2>
|
|
295
|
+
----
|
|
296
|
+
<1> Index of element to copy (0=top)
|
|
297
|
+
<2> Operator that copies indexed element
|
|
298
|
+
|
|
299
|
+
Where,
|
|
300
|
+
|
|
301
|
+
`n`:: Index from top (integer, 0=top element)
|
|
302
|
+
|
|
303
|
+
Stack effect: `anyn ... any0 n -- anyn ... any0 anyn`
|
|
304
|
+
|
|
305
|
+
=== Examples
|
|
306
|
+
|
|
307
|
+
[example]
|
|
308
|
+
====
|
|
309
|
+
[source,postscript]
|
|
310
|
+
----
|
|
311
|
+
10 20 30 0 index % [10 20 30 30] - copy top
|
|
312
|
+
10 20 30 2 index % [10 20 30 10] - copy 3rd from top
|
|
313
|
+
----
|
|
314
|
+
|
|
315
|
+
Access elements deep in the stack without removing them.
|
|
316
|
+
====
|
|
317
|
+
|
|
318
|
+
== Common Stack Patterns
|
|
319
|
+
|
|
320
|
+
=== Swapping operands
|
|
321
|
+
|
|
322
|
+
[example]
|
|
323
|
+
====
|
|
324
|
+
[source,postscript]
|
|
325
|
+
----
|
|
326
|
+
% Wrong order for subtraction
|
|
327
|
+
5 10 sub % -5 (10 - 5)
|
|
328
|
+
|
|
329
|
+
% Correct order
|
|
330
|
+
5 10 exch sub % 5 (5 - 10... wait, no)
|
|
331
|
+
10 5 sub % 5 (10 - 5)
|
|
332
|
+
----
|
|
333
|
+
|
|
334
|
+
Use `exch` to fix operand order.
|
|
335
|
+
====
|
|
336
|
+
|
|
337
|
+
=== Duplicating for reuse
|
|
338
|
+
|
|
339
|
+
[example]
|
|
340
|
+
====
|
|
341
|
+
[source,postscript]
|
|
342
|
+
----
|
|
343
|
+
% Calculate x² + 2x
|
|
344
|
+
5 dup dup mul % x² on stack: [25]
|
|
345
|
+
exch 2 mul add % 2x + x²: [25 10] → [35]
|
|
346
|
+
----
|
|
347
|
+
|
|
348
|
+
`dup` preserves values needed multiple times.
|
|
349
|
+
====
|
|
350
|
+
|
|
351
|
+
=== Cleaning up after operations
|
|
352
|
+
|
|
353
|
+
[example]
|
|
354
|
+
====
|
|
355
|
+
[source,postscript]
|
|
356
|
+
----
|
|
357
|
+
% Some operation leaves extra values
|
|
358
|
+
10 20 30 40 50 % [10 20 30 40 50]
|
|
359
|
+
% Only need top 2
|
|
360
|
+
3 -1 roll pop % Remove 3rd from top
|
|
361
|
+
pop % Remove another
|
|
362
|
+
% Now have [10 50]
|
|
363
|
+
----
|
|
364
|
+
|
|
365
|
+
Stack manipulation for cleanup.
|
|
366
|
+
====
|
|
367
|
+
|
|
368
|
+
== See Also
|
|
369
|
+
|
|
370
|
+
* link:../fundamentals.adoc#stack-based-execution-model[Stack Execution] -
|
|
371
|
+
How the stack works
|
|
372
|
+
* link:arithmetic.adoc[Arithmetic Operators] - Using stack for calculations
|
|
373
|
+
* link:control-flow.adoc[Control Flow] - Stack in loops and conditionals
|
|
374
|
+
* link:index.adoc[Back to Operator Reference]
|