Reputation: 260
I am making a high-level language on top of postscript for my course on compilers, and I want to create two functions: concatenate and union, which should take two paths and joints them. Concatenate works by connecting the end point of the first path to the start point of the second. Union works does not connect the end points.
After playing for a while, I managed to perform those operations automatically. I got the intended result in some cases, but not in others. I will give concrete examples of my solution, and where they fail.
WORKING: If I want to take two paths, one made by an arc, and other by connecting three dots, I can take the following basic paths:
newpath 100 200 70 0 45 arc %create an arc path
newpath 100 100 moveto 200 200 lineto 200 300 lineto %create a polygon
and concatenate them (creating a line from the endpoint of the arc to the start point of the lines) by letting my compiler write the code:
newpath 100 100 moveto 200 200 lineto 200 300 lineto reversepath currentpoint newpath %stores the startpoint of the polygon to be used later
newpath 100 200 70 0 45 arc % creates the arc
lineto %takes the saved information about start of the polygon and creates a line to it
100 100 moveto 200 200 lineto 200 300 lineto %finishes by adding the polygon to the path
STILL MISSING:
I am operating on the raw strings that I used to create those paths, but how to proceed in the case the user had create bindings for paths, and now I want to join them. For example, supposed the user create the binds:
/p1 { newpath 100 200 70 0 45 arc } bind def
/p2 { newpath 100 100 moveto 200 200 lineto 200 300 lineto } bind def
How could I proceed to join these two paths as needed WITHOUT modifying the bindings?
I tried something like
p1 uappend p2
, but it didnt work. I can find no help even after looking for many days.
Thanks
Upvotes: 1
Views: 232
Reputation: 19504
You can join two procedures fairly easily since they're just arrays.
% [a] [b] join [ab]
/join { 2 array astore [ exch {{}forall}forall ] } def
/p1p2 //p1 //p2 join cvx def
But, I repeat my comment: You should remove newpath
because it's just getting in the way. It's almost never needed in PostScript programming. It does a hard reset side-effect which is generally not a good thing to do in all your functions. Somehow it got into the tutorials so everybody does it, but it doesn't do anything useful IME.
p1 uappend p2
This code suggests "infix thinking" so as a first pass we should correct this to
p1 p2 uappend
But uappend
operates on user-path objects so you'll need to find an operator that takes the current path and returns a user path object.
Upvotes: 0
Reputation: 31199
You could load the definition of the functions and then look at the contents of the executable array.
/p1 load {==} forall
will show you what that looks like. Or you could define versions of each of the path operators which store their operands and just execute the procedures.
/moveto {....} def
/lineto {....} def
...
...
p1 p2
As usual with a programming problem there are multiple possible solutions.
Upvotes: 2