问题
I am currently writing a Logo to Postscript compiler. My PS output code doesn't seem to be valid. Any ideas what could be the problem? Or what the actual PostScript version for the LOGO should look like?
The LOGO input code
PROC LDRAGON ( LEVEL )
IF LEVEL == 0 THEN
FORWARD 5
ELSE
LDRAGON ( LEVEL - 1 )
LEFT 90
RDRAGON ( LEVEL - 1 )
ENDIF
PROC RDRAGON ( LEVEL )
IF LEVEL == 0 THEN
FORWARD 5
ELSE
LDRAGON ( LEVEL - 1 )
RIGHT 90
RDRAGON ( LEVEL - 1 )
ENDIF
PROC MAIN (VOID)
LDRAGON ( 11 )
The code from my compiler.
%!PS-Adobe-3.0
/Xpos { 300 } def showpage
/Ypos { 500 } def
/Heading { 0 } def
/Arg { 0 } def
/Right {
Heading exch add Trueheading
/Heading exch def
} def
/Left {
Heading exch sub Trueheading
/Heading exch def
} defп
/Trueheading {
360 mod dup
0 lt { 360 add } if
} def
/Forward {
dup Heading sin mul
exch Heading cos mul
2 copy Newposition
rlineto
} def
/Newposition {
Heading 180 gt Heading 360 lt
and { neg } if exch
Heading 90 gt Heading 270 lt
and { neg } if exch
Ypos add /Ypos exch def
Xpos add /Xpos exch def
} def
/LEVEL { 11 } def
/LDRAGON{
LEVEL
0
eq
{
5 FORWARD }{
LEVEL
1
1
sub
LDRAGON
90
LEFT
LEVEL
1
sub
RDRAGON
} ifelse
} def
/MAIN {
11
LDRAGON
} def
Xpos Ypos moveto
MAIN
stroke
showpage
回答1:
First problem is the opening comment line. The Adobe-3.0
part is not the Postscript version that the code uses, but the Document Structuring Conventions version that the file conforms to. Since you're not using any DSC comments at all, this first line should be %!PS
or just %!
.
Next, there are gibberish characters in left column of most lines. I'm guessing this is a an encoding for a TAB character, but it's not an ASCII tab. Safest policy is to always uses spaces for indentation.
The showpage
operator emits the output of the current page. It almost certainly should be at the end, not the beginning. ... Oh, I see it's at the bottom, too. The one at the top should be removed.
Next thing I see (although not technically a problem) is that addition is commutative. So exch add
can always be simplified to add
.
There's a typo at the end of the definition of Left
: defn
should be def
.
Heading 180 gt Heading 360 lt and
is always false. Perhaps you intended or
? ... Actually I think this part isn't necessary at all. Postscript's trig functions yield the appropriate signed-values for all quadrants.
This part looks like it has too many 1
s:
LEVEL
1
1
sub
LDRAGON
And RDRAGON
is not defined. Although since the functions are identical, you can reuse the same function body. /RDRAGON /LDRAGON load def
If the name LEVEL
in the LDRAGON
function should refer to the function's argument, then it must be explicitly defined. And it needs to define a local namespace, so it doesn't overwrite other instances of the same variable.
/LDRAGON{
1 dict begin
/LEVEL exch def
%...
end
And now that we have local dictionaries, re-defining a "global" variable (like Heading
, Xpos
, and Ypos
) should use store
instead of def
.
Postscript is case sensitive, so FORWARD
and Forward
are 2 distinct names.
Corrected Postscript program:
%!
%(debug.ps/db5.ps)run traceon stepon currentfile cvx debug
/Xpos { 300 } def
/Ypos { 500 } def
/Heading { 0 } def
/Arg { 0 } def
/Right {
Heading add Trueheading
/Heading exch store
} def
/Left {
Heading exch sub Trueheading
/Heading exch store
} def
/Trueheading {
360 mod dup
0 lt { 360 add } if
} def
/Forward {
dup Heading sin mul
exch Heading cos mul
2 copy Newposition
rlineto
} def
/Newposition {
Heading 180 gt Heading 360 lt
and { neg } if
exch
Heading 90 gt Heading 270 lt
and { neg } if exch
Ypos add /Ypos exch store
Xpos add /Xpos exch store
} def
/LEVEL { 11 } def
/LDRAGON{
1 dict begin
/LEVEL exch def
LEVEL
0
eq
{
5 Forward }{
LEVEL
1
sub
LDRAGON
90
Left
LEVEL
1
sub
RDRAGON
} ifelse
end
} def
/RDRAGON{
1 dict begin
/LEVEL exch def
LEVEL
0
eq
{
5 Forward }{
LEVEL
1
sub
LDRAGON
90
Right
LEVEL
1
sub
RDRAGON
} ifelse
end
} def
/MAIN {
11
LDRAGON
} def
Xpos Ypos moveto
MAIN
stroke
showpage
来源:https://stackoverflow.com/questions/22461743/logo-to-postscript-mini-compiler